]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
MdeModulePkg/SetupBrowserDxe: Do not reconnect driver with form-update
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
CommitLineData
7936fb6a 1/** @file\r
2Utility functions for UI presentation.\r
3\r
d1102dba 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
00d1c2a3 5(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7936fb6a 7\r
8**/\r
9\r
10#include "Setup.h"\r
7936fb6a 11\r
12BOOLEAN mHiiPackageListUpdated;\r
13UI_MENU_SELECTION *gCurrentSelection;\r
13ad1def
LG
14EFI_HII_HANDLE mCurrentHiiHandle = NULL;\r
15EFI_GUID mCurrentFormSetGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
16UINT16 mCurrentFormId = 0;\r
7c6c064c
ED
17EFI_EVENT mValueChangedEvent = NULL;\r
18LIST_ENTRY mRefreshEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList);\r
7c6c064c
ED
19UINT16 mCurFakeQestId;\r
20FORM_DISPLAY_ENGINE_FORM gDisplayFormData;\r
6fd184d0 21BOOLEAN mFinishRetrieveCall = FALSE;\r
365fdb0f 22BOOLEAN mDynamicFormUpdated = FALSE;\r
7c6c064c 23\r
034a3b4f 24/**\r
93373079 25 Check whether the ConfigAccess protocol is available.\r
034a3b4f 26\r
93373079 27 @param FormSet FormSet of which the ConfigAcces protocol need to be checked.\r
034a3b4f
GY
28\r
29 @retval EFI_SUCCESS The function executed successfully.\r
30\r
31**/\r
32EFI_STATUS\r
33CheckConfigAccess(\r
34 IN FORM_BROWSER_FORMSET *FormSet\r
35 )\r
36{\r
37 EFI_STATUS Status;\r
38\r
39 Status = gBS->HandleProtocol (\r
40 FormSet->DriverHandle,\r
41 &gEfiHiiConfigAccessProtocolGuid,\r
42 (VOID **) &FormSet->ConfigAccess\r
43 );\r
44 if (EFI_ERROR (Status)) {\r
45 //\r
46 // Configuration Driver don't attach ConfigAccess protocol to its HII package\r
47 // list, then there will be no configuration action required.\r
48 // Or the ConfigAccess protocol has been uninstalled.\r
49 //\r
50 FormSet->ConfigAccess = NULL;\r
51 }\r
52\r
53 return EFI_SUCCESS;\r
54}\r
55\r
7c6c064c
ED
56/**\r
57 Evaluate all expressions in a Form.\r
58\r
59 @param FormSet FormSet this Form belongs to.\r
60 @param Form The Form.\r
61\r
62 @retval EFI_SUCCESS The expression evaluated successfuly\r
63\r
64**/\r
65EFI_STATUS\r
66EvaluateFormExpressions (\r
67 IN FORM_BROWSER_FORMSET *FormSet,\r
68 IN FORM_BROWSER_FORM *Form\r
69 )\r
70{\r
71 EFI_STATUS Status;\r
72 LIST_ENTRY *Link;\r
73 FORM_EXPRESSION *Expression;\r
74\r
75 Link = GetFirstNode (&Form->ExpressionListHead);\r
76 while (!IsNull (&Form->ExpressionListHead, Link)) {\r
77 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
78 Link = GetNextNode (&Form->ExpressionListHead, Link);\r
79\r
80 if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||\r
81 Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||\r
1c0d306f 82 Expression->Type == EFI_HII_EXPRESSION_WARNING_IF ||\r
7c6c064c
ED
83 Expression->Type == EFI_HII_EXPRESSION_WRITE ||\r
84 (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {\r
85 //\r
86 // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.\r
87 //\r
88 continue;\r
89 }\r
90\r
91 Status = EvaluateExpression (FormSet, Form, Expression);\r
92 if (EFI_ERROR (Status)) {\r
93 return Status;\r
94 }\r
95 }\r
96\r
97 return EFI_SUCCESS;\r
98}\r
99\r
7c6c064c
ED
100/**\r
101 Base on the opcode buffer info to get the display statement.\r
102\r
103 @param OpCode The input opcode buffer for this statement.\r
d1102dba 104\r
7c6c064c
ED
105 @retval Statement The statement use this opcode buffer.\r
106\r
107**/\r
108FORM_DISPLAY_ENGINE_STATEMENT *\r
109GetDisplayStatement (\r
110 IN EFI_IFR_OP_HEADER *OpCode\r
111 )\r
112{\r
113 FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;\r
114 LIST_ENTRY *Link;\r
115\r
116 Link = GetFirstNode (&gDisplayFormData.StatementListHead);\r
117 while (!IsNull (&gDisplayFormData.StatementListHead, Link)) {\r
118 DisplayStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
119\r
120 if (DisplayStatement->OpCode == OpCode) {\r
121 return DisplayStatement;\r
122 }\r
123 Link = GetNextNode (&gDisplayFormData.StatementListHead, Link);\r
124 }\r
125\r
126 return NULL;\r
127}\r
128\r
129/**\r
130 Free the refresh event list.\r
131\r
132**/\r
d1102dba 133VOID\r
7c6c064c
ED
134FreeRefreshEvent (\r
135 VOID\r
136 )\r
137{\r
138 LIST_ENTRY *Link;\r
139 FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
140\r
141 while (!IsListEmpty (&mRefreshEventList)) {\r
142 Link = GetFirstNode (&mRefreshEventList);\r
143 EventNode = FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link);\r
144 RemoveEntryList (&EventNode->Link);\r
145\r
146 gBS->CloseEvent (EventNode->RefreshEvent);\r
147\r
148 FreePool (EventNode);\r
149 }\r
150}\r
151\r
152/**\r
d1102dba 153 Check whether this statement value is changed. If yes, update the statement value and return TRUE;\r
7c6c064c
ED
154 else return FALSE.\r
155\r
156 @param Statement The statement need to check.\r
157\r
158**/\r
159VOID\r
160UpdateStatement (\r
161 IN OUT FORM_BROWSER_STATEMENT *Statement\r
162 )\r
163{\r
164 GetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);\r
165\r
166 //\r
167 // Reset FormPackage update flag\r
168 //\r
169 mHiiPackageListUpdated = FALSE;\r
170\r
171 //\r
172 // Question value may be changed, need invoke its Callback()\r
173 //\r
798e4d22 174 ProcessCallBackFunction (gCurrentSelection, gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
d1102dba 175\r
7c6c064c
ED
176 if (mHiiPackageListUpdated) {\r
177 //\r
178 // Package list is updated, force to reparse IFR binary of target Formset\r
179 //\r
180 mHiiPackageListUpdated = FALSE;\r
181 gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
182 }\r
183}\r
184\r
185/**\r
186 Refresh the question which has refresh guid event attribute.\r
d1102dba
LG
187\r
188 @param Event The event which has this function related.\r
7c6c064c
ED
189 @param Context The input context info related to this event or the status code return to the caller.\r
190**/\r
191VOID\r
192EFIAPI\r
790447b2 193RefreshEventNotifyForStatement(\r
7c6c064c
ED
194 IN EFI_EVENT Event,\r
195 IN VOID *Context\r
196 )\r
197{\r
198 FORM_BROWSER_STATEMENT *Statement;\r
199\r
200 Statement = (FORM_BROWSER_STATEMENT *)Context;\r
201 UpdateStatement(Statement);\r
202 gBS->SignalEvent (mValueChangedEvent);\r
203}\r
204\r
790447b2
ED
205/**\r
206 Refresh the questions within this form.\r
d1102dba 207\r
790447b2
ED
208 @param Event The event which has this function related.\r
209 @param Context The input context info related to this event or the status code return to the caller.\r
210**/\r
211VOID\r
212EFIAPI\r
213RefreshEventNotifyForForm(\r
214 IN EFI_EVENT Event,\r
215 IN VOID *Context\r
216 )\r
217{\r
218 gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
219\r
220 gBS->SignalEvent (mValueChangedEvent);\r
221}\r
7c6c064c
ED
222\r
223/**\r
224 Create refresh hook event for statement which has refresh event or interval.\r
225\r
226 @param Statement The statement need to check.\r
227\r
228**/\r
229VOID\r
790447b2 230CreateRefreshEventForStatement (\r
7c6c064c
ED
231 IN FORM_BROWSER_STATEMENT *Statement\r
232 )\r
233{\r
234 EFI_STATUS Status;\r
235 EFI_EVENT RefreshEvent;\r
236 FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
237\r
238 //\r
239 // If question has refresh guid, create the notify function.\r
240 //\r
241 Status = gBS->CreateEventEx (\r
242 EVT_NOTIFY_SIGNAL,\r
243 TPL_CALLBACK,\r
790447b2 244 RefreshEventNotifyForStatement,\r
7c6c064c
ED
245 Statement,\r
246 &Statement->RefreshGuid,\r
247 &RefreshEvent);\r
248 ASSERT_EFI_ERROR (Status);\r
249\r
250 EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
251 ASSERT (EventNode != NULL);\r
252 EventNode->RefreshEvent = RefreshEvent;\r
253 InsertTailList(&mRefreshEventList, &EventNode->Link);\r
254}\r
255\r
790447b2 256/**\r
1f9837b4 257 Create refresh hook event for form which has refresh event or interval.\r
790447b2 258\r
1f9837b4 259 @param Form The form need to check.\r
790447b2
ED
260\r
261**/\r
262VOID\r
263CreateRefreshEventForForm (\r
264 IN FORM_BROWSER_FORM *Form\r
265 )\r
266{\r
267 EFI_STATUS Status;\r
268 EFI_EVENT RefreshEvent;\r
269 FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
270\r
271 //\r
272 // If question has refresh guid, create the notify function.\r
273 //\r
274 Status = gBS->CreateEventEx (\r
275 EVT_NOTIFY_SIGNAL,\r
276 TPL_CALLBACK,\r
277 RefreshEventNotifyForForm,\r
278 Form,\r
279 &Form->RefreshGuid,\r
280 &RefreshEvent);\r
281 ASSERT_EFI_ERROR (Status);\r
282\r
283 EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
284 ASSERT (EventNode != NULL);\r
285 EventNode->RefreshEvent = RefreshEvent;\r
286 InsertTailList(&mRefreshEventList, &EventNode->Link);\r
287}\r
288\r
7c6c064c
ED
289/**\r
290\r
291 Initialize the Display statement structure data.\r
292\r
293 @param DisplayStatement Pointer to the display Statement data strucure.\r
294 @param Statement The statement need to check.\r
7c6c064c
ED
295**/\r
296VOID\r
297InitializeDisplayStatement (\r
298 IN OUT FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement,\r
077c7aee 299 IN FORM_BROWSER_STATEMENT *Statement\r
7c6c064c
ED
300 )\r
301{\r
302 LIST_ENTRY *Link;\r
303 QUESTION_OPTION *Option;\r
304 DISPLAY_QUESTION_OPTION *DisplayOption;\r
077c7aee 305 FORM_DISPLAY_ENGINE_STATEMENT *ParentStatement;\r
7c6c064c
ED
306\r
307 DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
308 DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
309 DisplayStatement->OpCode = Statement->OpCode;\r
310 InitializeListHead (&DisplayStatement->NestStatementList);\r
311 InitializeListHead (&DisplayStatement->OptionListHead);\r
312\r
313 if ((EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut) || Statement->Locked) {\r
314 DisplayStatement->Attribute |= HII_DISPLAY_GRAYOUT;\r
315 }\r
316 if ((Statement->ValueExpression != NULL) || ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {\r
317 DisplayStatement->Attribute |= HII_DISPLAY_READONLY;\r
318 }\r
319\r
320 //\r
321 // Initilize the option list in statement.\r
322 //\r
323 Link = GetFirstNode (&Statement->OptionListHead);\r
324 while (!IsNull (&Statement->OptionListHead, Link)) {\r
325 Option = QUESTION_OPTION_FROM_LINK (Link);\r
326 Link = GetNextNode (&Statement->OptionListHead, Link);\r
327 if ((Option->SuppressExpression != NULL) &&\r
328 ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {\r
329 continue;\r
330 }\r
331\r
332 DisplayOption = AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION));\r
333 ASSERT (DisplayOption != NULL);\r
334\r
335 DisplayOption->ImageId = Option->ImageId;\r
336 DisplayOption->Signature = DISPLAY_QUESTION_OPTION_SIGNATURE;\r
337 DisplayOption->OptionOpCode = Option->OpCode;\r
338 InsertTailList(&DisplayStatement->OptionListHead, &DisplayOption->Link);\r
339 }\r
340\r
341 CopyMem (&DisplayStatement->CurrentValue, &Statement->HiiValue, sizeof (EFI_HII_VALUE));\r
342\r
343 //\r
344 // Some special op code need an extra buffer to save the data.\r
345 // Such as string, password, orderedlist...\r
346 //\r
347 if (Statement->BufferValue != NULL) {\r
348 //\r
349 // Ordered list opcode may not initilized, get default value here.\r
350 //\r
351 if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP && GetArrayData (Statement->BufferValue, Statement->ValueType, 0) == 0) {\r
352 GetQuestionDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, 0);\r
353 }\r
354\r
355 DisplayStatement->CurrentValue.Buffer = AllocateCopyPool(Statement->StorageWidth,Statement->BufferValue);\r
356 DisplayStatement->CurrentValue.BufferLen = Statement->StorageWidth;\r
357 }\r
358\r
359 DisplayStatement->SettingChangedFlag = Statement->ValueChanged;\r
360\r
361 //\r
362 // Get the highlight statement for current form.\r
363 //\r
364 if (((gCurrentSelection->QuestionId != 0) && (Statement->QuestionId == gCurrentSelection->QuestionId)) ||\r
365 ((mCurFakeQestId != 0) && (Statement->FakeQuestionId == mCurFakeQestId))) {\r
366 gDisplayFormData.HighLightedStatement = DisplayStatement;\r
367 }\r
368\r
369 //\r
370 // Create the refresh event process function.\r
371 //\r
39cde03c 372 if (!IsZeroGuid (&Statement->RefreshGuid)) {\r
790447b2 373 CreateRefreshEventForStatement (Statement);\r
7c6c064c
ED
374 }\r
375\r
376 //\r
377 // For RTC type of date/time, set default refresh interval to be 1 second.\r
378 //\r
379 if ((Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) && Statement->Storage == NULL) {\r
380 Statement->RefreshInterval = 1;\r
381 }\r
382\r
383 //\r
384 // Create the refresh guid hook event.\r
385 // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.\r
386 //\r
39cde03c 387 if ((!IsZeroGuid (&Statement->RefreshGuid)) || (Statement->RefreshInterval != 0)) {\r
7c6c064c
ED
388 gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
389 }\r
390\r
391 //\r
392 // Save the password check function for later use.\r
393 //\r
394 if (Statement->Operand == EFI_IFR_PASSWORD_OP) {\r
395 DisplayStatement->PasswordCheck = PasswordCheck;\r
396 }\r
397\r
7c6c064c
ED
398 //\r
399 // If this statement is nest in the subtitle, insert to the host statement.\r
400 // else insert to the form it belongs to.\r
401 //\r
077c7aee
ED
402 if (Statement->ParentStatement != NULL) {\r
403 ParentStatement = GetDisplayStatement(Statement->ParentStatement->OpCode);\r
404 ASSERT (ParentStatement != NULL);\r
405 InsertTailList(&ParentStatement->NestStatementList, &DisplayStatement->DisplayLink);\r
7c6c064c
ED
406 } else {\r
407 InsertTailList(&gDisplayFormData.StatementListHead, &DisplayStatement->DisplayLink);\r
408 }\r
409}\r
410\r
411/**\r
412 Process for the refresh interval statement.\r
413\r
414 @param Event The Event need to be process\r
415 @param Context The context of the event.\r
416\r
417**/\r
418VOID\r
419EFIAPI\r
420RefreshIntervalProcess (\r
421 IN EFI_EVENT Event,\r
422 IN VOID *Context\r
423 )\r
424{\r
425 FORM_BROWSER_STATEMENT *Statement;\r
426 LIST_ENTRY *Link;\r
427\r
428 Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
429 while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
430 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
431 Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
432\r
433 if (Statement->RefreshInterval == 0) {\r
434 continue;\r
435 }\r
436\r
437 UpdateStatement(Statement);\r
438 }\r
439\r
440 gBS->SignalEvent (mValueChangedEvent);\r
441}\r
442\r
443/**\r
444\r
445 Make a copy of the global hotkey info.\r
446\r
447**/\r
448VOID\r
449UpdateHotkeyList (\r
450 VOID\r
451 )\r
452{\r
453 BROWSER_HOT_KEY *HotKey;\r
454 BROWSER_HOT_KEY *CopyKey;\r
455 LIST_ENTRY *Link;\r
456\r
457 Link = GetFirstNode (&gBrowserHotKeyList);\r
458 while (!IsNull (&gBrowserHotKeyList, Link)) {\r
459 HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
460\r
461 CopyKey = AllocateCopyPool(sizeof (BROWSER_HOT_KEY), HotKey);\r
523f48e7 462 ASSERT (CopyKey != NULL);\r
7c6c064c 463 CopyKey->KeyData = AllocateCopyPool(sizeof (EFI_INPUT_KEY), HotKey->KeyData);\r
523f48e7 464 ASSERT (CopyKey->KeyData != NULL);\r
7c6c064c 465 CopyKey->HelpString = AllocateCopyPool(StrSize (HotKey->HelpString), HotKey->HelpString);\r
523f48e7 466 ASSERT (CopyKey->HelpString != NULL);\r
7c6c064c
ED
467\r
468 InsertTailList(&gDisplayFormData.HotKeyListHead, &CopyKey->Link);\r
469\r
470 Link = GetNextNode (&gBrowserHotKeyList, Link);\r
471 }\r
472}\r
b9feb4bd 473\r
184f3a02
ED
474/**\r
475\r
476 Get the extra question attribute from override question list.\r
477\r
478 @param QuestionId The question id for this request question.\r
479\r
d1102dba 480 @retval The attribute for this question or NULL if not found this\r
184f3a02
ED
481 question in the list.\r
482\r
483**/\r
d1102dba 484UINT32\r
184f3a02
ED
485ProcessQuestionExtraAttr (\r
486 IN EFI_QUESTION_ID QuestionId\r
487 )\r
488{\r
489 LIST_ENTRY *Link;\r
490 QUESTION_ATTRIBUTE_OVERRIDE *QuestionDesc;\r
491\r
492 //\r
493 // Return HII_DISPLAY_NONE if input a invalid question id.\r
494 //\r
495 if (QuestionId == 0) {\r
496 return HII_DISPLAY_NONE;\r
497 }\r
498\r
499 Link = GetFirstNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead);\r
500 while (!IsNull (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link)) {\r
501 QuestionDesc = FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link);\r
502 Link = GetNextNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link);\r
503\r
504 if ((QuestionDesc->QuestionId == QuestionId) &&\r
505 (QuestionDesc->FormId == gCurrentSelection->FormId) &&\r
506 (QuestionDesc->HiiHandle == gCurrentSelection->Handle) &&\r
507 CompareGuid (&QuestionDesc->FormSetGuid, &gCurrentSelection->FormSetGuid)) {\r
508 return QuestionDesc->Attribute;\r
509 }\r
510 }\r
511\r
512 return HII_DISPLAY_NONE;\r
513}\r
514\r
b9feb4bd 515/**\r
b9feb4bd 516\r
7c6c064c
ED
517 Enum all statement in current form, find all the statement can be display and\r
518 add to the display form.\r
b9feb4bd
ED
519\r
520**/\r
521VOID\r
7c6c064c
ED
522AddStatementToDisplayForm (\r
523 VOID\r
524 )\r
525{\r
526 EFI_STATUS Status;\r
527 LIST_ENTRY *Link;\r
528 FORM_BROWSER_STATEMENT *Statement;\r
529 FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;\r
7c6c064c
ED
530 UINT8 MinRefreshInterval;\r
531 EFI_EVENT RefreshIntervalEvent;\r
532 FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
533 BOOLEAN FormEditable;\r
184f3a02 534 UINT32 ExtraAttribute;\r
7c6c064c 535\r
7c6c064c
ED
536 MinRefreshInterval = 0;\r
537 FormEditable = FALSE;\r
538\r
539 //\r
540 // Process the statement outside the form, these statements are not recognized\r
541 // by browser core.\r
542 //\r
543 Link = GetFirstNode (&gCurrentSelection->FormSet->StatementListOSF);\r
544 while (!IsNull (&gCurrentSelection->FormSet->StatementListOSF, Link)) {\r
545 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
546 Link = GetNextNode (&gCurrentSelection->FormSet->StatementListOSF, Link);\r
547\r
548 DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
549 ASSERT (DisplayStatement != NULL);\r
550 DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
551 DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
552 DisplayStatement->OpCode = Statement->OpCode;\r
553\r
554 InitializeListHead (&DisplayStatement->NestStatementList);\r
555 InitializeListHead (&DisplayStatement->OptionListHead);\r
556\r
557 InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
558 }\r
559\r
5e30b69e
DB
560 //\r
561 // treat formset as statement outside the form,get its opcode.\r
562 //\r
563 DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
564 ASSERT (DisplayStatement != NULL);\r
565\r
566 DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
567 DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
568 DisplayStatement->OpCode = gCurrentSelection->FormSet->OpCode;\r
569\r
570 InitializeListHead (&DisplayStatement->NestStatementList);\r
571 InitializeListHead (&DisplayStatement->OptionListHead);\r
572\r
573 InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
574\r
7c6c064c
ED
575 //\r
576 // Process the statement in this form.\r
577 //\r
578 Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
579 while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
580 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
581 Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
582\r
583 //\r
584 // This statement can't be show, skip it.\r
585 //\r
586 if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) > ExpressGrayOut) {\r
587 continue;\r
588 }\r
589\r
184f3a02
ED
590 //\r
591 // Check the extra attribute.\r
592 //\r
593 ExtraAttribute = ProcessQuestionExtraAttr (Statement->QuestionId);\r
594 if ((ExtraAttribute & HII_DISPLAY_SUPPRESS) != 0) {\r
595 continue;\r
596 }\r
597\r
7c6c064c
ED
598 DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
599 ASSERT (DisplayStatement != NULL);\r
600\r
601 //\r
602 // Initialize this statement and add it to the display form.\r
603 //\r
077c7aee 604 InitializeDisplayStatement(DisplayStatement, Statement);\r
7c6c064c 605\r
184f3a02
ED
606 //\r
607 // Set the extra attribute.\r
608 //\r
609 DisplayStatement->Attribute |= ExtraAttribute;\r
610\r
7c6c064c
ED
611 if (Statement->Storage != NULL) {\r
612 FormEditable = TRUE;\r
613 }\r
614\r
615 //\r
616 // Get the minimal refresh interval value for later use.\r
617 //\r
d1102dba 618 if ((Statement->RefreshInterval != 0) &&\r
7c6c064c
ED
619 (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval)) {\r
620 MinRefreshInterval = Statement->RefreshInterval;\r
621 }\r
622 }\r
623\r
624 //\r
625 // Create the periodic timer for refresh interval statement.\r
626 //\r
627 if (MinRefreshInterval != 0) {\r
628 Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshIntervalProcess, NULL, &RefreshIntervalEvent);\r
629 ASSERT_EFI_ERROR (Status);\r
630 Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, MinRefreshInterval * ONE_SECOND);\r
631 ASSERT_EFI_ERROR (Status);\r
632\r
633 EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
634 ASSERT (EventNode != NULL);\r
635 EventNode->RefreshEvent = RefreshIntervalEvent;\r
636 InsertTailList(&mRefreshEventList, &EventNode->Link);\r
637 }\r
638\r
790447b2
ED
639 //\r
640 // Create the refresh event process function for Form.\r
641 //\r
39cde03c 642 if (!IsZeroGuid (&gCurrentSelection->Form->RefreshGuid)) {\r
790447b2
ED
643 CreateRefreshEventForForm (gCurrentSelection->Form);\r
644 if (gDisplayFormData.FormRefreshEvent == NULL) {\r
645 gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
646 }\r
647 }\r
648\r
7c6c064c
ED
649 //\r
650 // Update hotkey list field.\r
651 //\r
652 if (gBrowserSettingScope == SystemLevel || FormEditable) {\r
653 UpdateHotkeyList();\r
654 }\r
655}\r
656\r
657/**\r
658\r
659 Initialize the SettingChangedFlag variable in the display form.\r
660\r
661**/\r
662VOID\r
663UpdateDataChangedFlag (\r
664 VOID\r
665 )\r
666{\r
667 LIST_ENTRY *Link;\r
668 FORM_BROWSER_FORMSET *LocalFormSet;\r
669\r
670 gDisplayFormData.SettingChangedFlag = FALSE;\r
671\r
672 if (IsNvUpdateRequiredForForm (gCurrentSelection->Form)) {\r
673 gDisplayFormData.SettingChangedFlag = TRUE;\r
674 return;\r
675 }\r
676\r
677 //\r
678 // Base on the system level to check whether need to show the NV flag.\r
d1102dba 679 //\r
7c6c064c
ED
680 switch (gBrowserSettingScope) {\r
681 case SystemLevel:\r
682 //\r
683 // Check the maintain list to see whether there is any change.\r
684 //\r
685 Link = GetFirstNode (&gBrowserFormSetList);\r
686 while (!IsNull (&gBrowserFormSetList, Link)) {\r
687 LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
688 if (IsNvUpdateRequiredForFormSet(LocalFormSet)) {\r
689 gDisplayFormData.SettingChangedFlag = TRUE;\r
690 return;\r
691 }\r
692 Link = GetNextNode (&gBrowserFormSetList, Link);\r
693 }\r
694 break;\r
695\r
696 case FormSetLevel:\r
697 if (IsNvUpdateRequiredForFormSet(gCurrentSelection->FormSet)) {\r
698 gDisplayFormData.SettingChangedFlag = TRUE;\r
699 return;\r
700 }\r
701 break;\r
702\r
703 default:\r
704 break;\r
705 }\r
706}\r
707\r
708/**\r
709\r
710 Initialize the Display form structure data.\r
711\r
712**/\r
713VOID\r
714InitializeDisplayFormData (\r
715 VOID\r
716 )\r
717{\r
718 EFI_STATUS Status;\r
719\r
720 gDisplayFormData.Signature = FORM_DISPLAY_ENGINE_FORM_SIGNATURE;\r
721 gDisplayFormData.Version = FORM_DISPLAY_ENGINE_VERSION_1;\r
722 gDisplayFormData.ImageId = 0;\r
723 gDisplayFormData.AnimationId = 0;\r
724\r
725 InitializeListHead (&gDisplayFormData.StatementListHead);\r
726 InitializeListHead (&gDisplayFormData.StatementListOSF);\r
727 InitializeListHead (&gDisplayFormData.HotKeyListHead);\r
728\r
729 Status = gBS->CreateEvent (\r
d1102dba 730 EVT_NOTIFY_WAIT,\r
7c6c064c 731 TPL_CALLBACK,\r
ac72474d 732 EfiEventEmptyFunction,\r
7c6c064c
ED
733 NULL,\r
734 &mValueChangedEvent\r
735 );\r
d1102dba 736 ASSERT_EFI_ERROR (Status);\r
7c6c064c
ED
737}\r
738\r
739/**\r
740\r
741 Free the kotkey info saved in form data.\r
742\r
743**/\r
744VOID\r
745FreeHotkeyList (\r
746 VOID\r
747 )\r
748{\r
749 BROWSER_HOT_KEY *HotKey;\r
750 LIST_ENTRY *Link;\r
751\r
752 while (!IsListEmpty (&gDisplayFormData.HotKeyListHead)) {\r
753 Link = GetFirstNode (&gDisplayFormData.HotKeyListHead);\r
754 HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
755\r
756 RemoveEntryList (&HotKey->Link);\r
757\r
758 FreePool (HotKey->KeyData);\r
759 FreePool (HotKey->HelpString);\r
760 FreePool (HotKey);\r
761 }\r
762}\r
763\r
764/**\r
765\r
766 Update the Display form structure data.\r
767\r
768**/\r
769VOID\r
770UpdateDisplayFormData (\r
771 VOID\r
772 )\r
773{\r
774 gDisplayFormData.FormTitle = gCurrentSelection->Form->FormTitle;\r
775 gDisplayFormData.FormId = gCurrentSelection->FormId;\r
776 gDisplayFormData.HiiHandle = gCurrentSelection->Handle;\r
777 CopyGuid (&gDisplayFormData.FormSetGuid, &gCurrentSelection->FormSetGuid);\r
778\r
779 gDisplayFormData.Attribute = 0;\r
780 gDisplayFormData.Attribute |= gCurrentSelection->Form->ModalForm ? HII_DISPLAY_MODAL : 0;\r
781 gDisplayFormData.Attribute |= gCurrentSelection->Form->Locked ? HII_DISPLAY_LOCK : 0;\r
782\r
783 gDisplayFormData.FormRefreshEvent = NULL;\r
784 gDisplayFormData.HighLightedStatement = NULL;\r
785\r
7c6c064c
ED
786 UpdateDataChangedFlag ();\r
787\r
788 AddStatementToDisplayForm ();\r
789}\r
790\r
791/**\r
792\r
793 Free the Display Statement structure data.\r
794\r
795 @param StatementList Point to the statement list which need to be free.\r
796\r
797**/\r
798VOID\r
799FreeStatementData (\r
800 LIST_ENTRY *StatementList\r
801 )\r
802{\r
803 LIST_ENTRY *Link;\r
804 LIST_ENTRY *OptionLink;\r
805 FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
806 DISPLAY_QUESTION_OPTION *Option;\r
807\r
808 //\r
809 // Free Statements/Questions\r
810 //\r
811 while (!IsListEmpty (StatementList)) {\r
812 Link = GetFirstNode (StatementList);\r
813 Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
814\r
815 //\r
816 // Free Options List\r
817 //\r
818 while (!IsListEmpty (&Statement->OptionListHead)) {\r
819 OptionLink = GetFirstNode (&Statement->OptionListHead);\r
820 Option = DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink);\r
821 RemoveEntryList (&Option->Link);\r
822 FreePool (Option);\r
823 }\r
824\r
825 //\r
826 // Free nest statement List\r
827 //\r
828 if (!IsListEmpty (&Statement->NestStatementList)) {\r
829 FreeStatementData(&Statement->NestStatementList);\r
830 }\r
831\r
832 RemoveEntryList (&Statement->DisplayLink);\r
833 FreePool (Statement);\r
834 }\r
835}\r
836\r
837/**\r
838\r
839 Free the Display form structure data.\r
840\r
841**/\r
842VOID\r
843FreeDisplayFormData (\r
844 VOID\r
845 )\r
846{\r
847 FreeStatementData (&gDisplayFormData.StatementListHead);\r
848 FreeStatementData (&gDisplayFormData.StatementListOSF);\r
849\r
850 FreeRefreshEvent();\r
851\r
852 FreeHotkeyList();\r
853}\r
854\r
855/**\r
856\r
857 Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.\r
858\r
859 @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.\r
860\r
861 @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.\r
862\r
863**/\r
864FORM_BROWSER_STATEMENT *\r
865GetBrowserStatement (\r
866 IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement\r
867 )\r
868{\r
869 FORM_BROWSER_STATEMENT *Statement;\r
870 LIST_ENTRY *Link;\r
871\r
872 Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
873 while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
874 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
875\r
876 if (Statement->OpCode == DisplayStatement->OpCode) {\r
877 return Statement;\r
878 }\r
879\r
880 Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
881 }\r
882\r
883 return NULL;\r
884}\r
885\r
892eccc8
ED
886/**\r
887 Update the ValueChanged status for questions in this form.\r
888\r
889 @param FormSet FormSet data structure.\r
890 @param Form Form data structure.\r
891\r
892**/\r
d1102dba 893VOID\r
892eccc8
ED
894UpdateStatementStatusForForm (\r
895 IN FORM_BROWSER_FORMSET *FormSet,\r
896 IN FORM_BROWSER_FORM *Form\r
897 )\r
898{\r
899 LIST_ENTRY *Link;\r
900 FORM_BROWSER_STATEMENT *Question;\r
901\r
902 Link = GetFirstNode (&Form->StatementListHead);\r
903 while (!IsNull (&Form->StatementListHead, Link)) {\r
904 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
905 Link = GetNextNode (&Form->StatementListHead, Link);\r
906\r
93551a01
ED
907 //\r
908 // For password opcode, not set the the value changed flag.\r
909 //\r
910 if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
911 continue;\r
912 }\r
913\r
892eccc8
ED
914 IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBuffer);\r
915 }\r
916}\r
917\r
918/**\r
919 Update the ValueChanged status for questions in this formset.\r
920\r
921 @param FormSet FormSet data structure.\r
922\r
923**/\r
d1102dba 924VOID\r
892eccc8
ED
925UpdateStatementStatusForFormSet (\r
926 IN FORM_BROWSER_FORMSET *FormSet\r
927 )\r
928{\r
929 LIST_ENTRY *Link;\r
930 FORM_BROWSER_FORM *Form;\r
931\r
932 Link = GetFirstNode (&FormSet->FormListHead);\r
933 while (!IsNull (&FormSet->FormListHead, Link)) {\r
934 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
935 Link = GetNextNode (&FormSet->FormListHead, Link);\r
936\r
937 UpdateStatementStatusForForm (FormSet, Form);\r
938 }\r
939}\r
940\r
941/**\r
942 Update the ValueChanged status for questions.\r
943\r
944 @param FormSet FormSet data structure.\r
945 @param Form Form data structure.\r
946 @param SettingScope Setting Scope for Default action.\r
947\r
948**/\r
d1102dba 949VOID\r
892eccc8
ED
950UpdateStatementStatus (\r
951 IN FORM_BROWSER_FORMSET *FormSet,\r
d1102dba 952 IN FORM_BROWSER_FORM *Form,\r
892eccc8
ED
953 IN BROWSER_SETTING_SCOPE SettingScope\r
954 )\r
955{\r
956 LIST_ENTRY *Link;\r
957 FORM_BROWSER_FORMSET *LocalFormSet;\r
958\r
959 switch (SettingScope) {\r
960 case SystemLevel:\r
961 Link = GetFirstNode (&gBrowserFormSetList);\r
962 while (!IsNull (&gBrowserFormSetList, Link)) {\r
963 LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
964 Link = GetNextNode (&gBrowserFormSetList, Link);\r
965 if (!ValidateFormSet(LocalFormSet)) {\r
966 continue;\r
967 }\r
968\r
969 UpdateStatementStatusForFormSet (LocalFormSet);\r
970 }\r
971 break;\r
972\r
973 case FormSetLevel:\r
974 UpdateStatementStatusForFormSet (FormSet);\r
975 break;\r
976\r
977 case FormLevel:\r
978 UpdateStatementStatusForForm (FormSet, Form);\r
979 break;\r
980\r
981 default:\r
982 break;\r
983 }\r
984}\r
985\r
7c6c064c
ED
986/**\r
987\r
988 Process the action request in user input.\r
989\r
990 @param Action The user input action request info.\r
991 @param DefaultId The user input default Id info.\r
992\r
993 @retval EFI_SUCESSS This function always return successfully for now.\r
994\r
995**/\r
d1102dba 996EFI_STATUS\r
7c6c064c
ED
997ProcessAction (\r
998 IN UINT32 Action,\r
999 IN UINT16 DefaultId\r
1000 )\r
1001{\r
7c6c064c
ED
1002 //\r
1003 // This is caused by use press ESC, and it should not combine with other action type.\r
1004 //\r
1005 if ((Action & BROWSER_ACTION_FORM_EXIT) == BROWSER_ACTION_FORM_EXIT) {\r
1006 FindNextMenu (gCurrentSelection, FormLevel);\r
1007 return EFI_SUCCESS;\r
1008 }\r
1009\r
1010 //\r
1011 // Below is normal hotkey trigged action, these action maybe combine with each other.\r
1012 //\r
1013 if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
1014 DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
1015 }\r
1016\r
1017 if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
787fc2a6 1018 ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE, FALSE);\r
892eccc8 1019 UpdateStatementStatus (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
7c6c064c
ED
1020 }\r
1021\r
1022 if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {\r
4d4deaac 1023 SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
7c6c064c
ED
1024 }\r
1025\r
1026 if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
b2dcae4c
BD
1027 gResetRequiredFormLevel = TRUE;\r
1028 gResetRequiredSystemLevel = TRUE;\r
7c6c064c
ED
1029 }\r
1030\r
1031 if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
1032 //\r
1033 // Form Exit without saving, Similar to ESC Key.\r
1034 // FormSet Exit without saving, Exit SendForm.\r
1035 // System Exit without saving, CallExitHandler and Exit SendForm.\r
1036 //\r
1037 DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
1038 if (gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) {\r
1039 FindNextMenu (gCurrentSelection, gBrowserSettingScope);\r
1040 } else if (gBrowserSettingScope == SystemLevel) {\r
1041 if (ExitHandlerFunction != NULL) {\r
1042 ExitHandlerFunction ();\r
1043 }\r
1044 gCurrentSelection->Action = UI_ACTION_EXIT;\r
1045 }\r
1046 }\r
1047\r
1048 return EFI_SUCCESS;\r
1049}\r
1050\r
07d7dbae
ED
1051/**\r
1052 Check whether the formset guid is in this Hii package list.\r
1053\r
1054 @param HiiHandle The HiiHandle for this HII package list.\r
8a639069 1055 @param FormSetGuid The formset guid for the request formset.\r
07d7dbae
ED
1056\r
1057 @retval TRUE Find the formset guid.\r
1058 @retval FALSE Not found the formset guid.\r
1059\r
1060**/\r
1061BOOLEAN\r
1062GetFormsetGuidFromHiiHandle (\r
1063 IN EFI_HII_HANDLE HiiHandle,\r
1064 IN EFI_GUID *FormSetGuid\r
1065 )\r
1066{\r
1067 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
1068 UINTN BufferSize;\r
1069 UINT32 Offset;\r
1070 UINT32 Offset2;\r
1071 UINT32 PackageListLength;\r
1072 EFI_HII_PACKAGE_HEADER PackageHeader;\r
1073 UINT8 *Package;\r
1074 UINT8 *OpCodeData;\r
1075 EFI_STATUS Status;\r
1076 BOOLEAN FindGuid;\r
1077\r
1078 BufferSize = 0;\r
1079 HiiPackageList = NULL;\r
1080 FindGuid = FALSE;\r
d1102dba 1081\r
07d7dbae
ED
1082 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
1083 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1084 HiiPackageList = AllocatePool (BufferSize);\r
1085 ASSERT (HiiPackageList != NULL);\r
1086\r
1087 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
1088 }\r
1089 if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
1090 return FALSE;\r
1091 }\r
1092\r
1093 //\r
1094 // Get Form package from this HII package List\r
1095 //\r
1096 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
1097 Offset2 = 0;\r
d1102dba 1098 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
07d7dbae
ED
1099\r
1100 while (Offset < PackageListLength) {\r
1101 Package = ((UINT8 *) HiiPackageList) + Offset;\r
1102 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
1103 Offset += PackageHeader.Length;\r
1104\r
1105 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
1106 //\r
1107 // Search FormSet in this Form Package\r
1108 //\r
1109 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
1110 while (Offset2 < PackageHeader.Length) {\r
1111 OpCodeData = Package + Offset2;\r
1112\r
1113 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
1114 if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))){\r
1115 FindGuid = TRUE;\r
1116 break;\r
1117 }\r
1118 }\r
1119\r
1120 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
1121 }\r
1122 }\r
1123 if (FindGuid) {\r
1124 break;\r
1125 }\r
1126 }\r
1127\r
1128 FreePool (HiiPackageList);\r
1129\r
1130 return FindGuid;\r
1131}\r
7c6c064c
ED
1132\r
1133/**\r
1134 Find HII Handle in the HII database associated with given Device Path.\r
1135\r
1136 If DevicePath is NULL, then ASSERT.\r
1137\r
1138 @param DevicePath Device Path associated with the HII package list\r
1139 handle.\r
07d7dbae 1140 @param FormsetGuid The formset guid for this formset.\r
7c6c064c
ED
1141\r
1142 @retval Handle HII package list Handle associated with the Device\r
1143 Path.\r
1144 @retval NULL Hii Package list handle is not found.\r
1145\r
1146**/\r
1147EFI_HII_HANDLE\r
7c6c064c 1148DevicePathToHiiHandle (\r
07d7dbae
ED
1149 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1150 IN EFI_GUID *FormsetGuid\r
7936fb6a 1151 )\r
1152{\r
7c6c064c
ED
1153 EFI_STATUS Status;\r
1154 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
7c6c064c
ED
1155 UINTN Index;\r
1156 EFI_HANDLE Handle;\r
1157 EFI_HANDLE DriverHandle;\r
1158 EFI_HII_HANDLE *HiiHandles;\r
1159 EFI_HII_HANDLE HiiHandle;\r
1160\r
1161 ASSERT (DevicePath != NULL);\r
1162\r
1163 TmpDevicePath = DevicePath;\r
1164 //\r
1165 // Locate Device Path Protocol handle buffer\r
1166 //\r
1167 Status = gBS->LocateDevicePath (\r
1168 &gEfiDevicePathProtocolGuid,\r
1169 &TmpDevicePath,\r
1170 &DriverHandle\r
1171 );\r
1172 if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {\r
1173 return NULL;\r
1174 }\r
7936fb6a 1175\r
1176 //\r
7c6c064c 1177 // Retrieve all HII Handles from HII database\r
7936fb6a 1178 //\r
07d7dbae
ED
1179 HiiHandles = HiiGetHiiHandles (NULL);\r
1180 if (HiiHandles == NULL) {\r
7c6c064c
ED
1181 return NULL;\r
1182 }\r
b9feb4bd 1183\r
7936fb6a 1184 //\r
7c6c064c 1185 // Search Hii Handle by Driver Handle\r
7936fb6a 1186 //\r
7c6c064c 1187 HiiHandle = NULL;\r
07d7dbae 1188 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
7c6c064c
ED
1189 Status = mHiiDatabase->GetPackageListHandle (\r
1190 mHiiDatabase,\r
1191 HiiHandles[Index],\r
1192 &Handle\r
1193 );\r
1194 if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
07d7dbae
ED
1195 if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], FormsetGuid)) {\r
1196 HiiHandle = HiiHandles[Index];\r
1197 break;\r
1198 }\r
1199\r
1200 if (HiiHandle != NULL) {\r
1201 break;\r
1202 }\r
7c6c064c
ED
1203 }\r
1204 }\r
1205\r
1206 FreePool (HiiHandles);\r
1207 return HiiHandle;\r
1208}\r
1209\r
1210/**\r
1211 Find HII Handle in the HII database associated with given form set guid.\r
1212\r
1213 If FormSetGuid is NULL, then ASSERT.\r
1214\r
1215 @param ComparingGuid FormSet Guid associated with the HII package list\r
1216 handle.\r
1217\r
1218 @retval Handle HII package list Handle associated with the Device\r
1219 Path.\r
1220 @retval NULL Hii Package list handle is not found.\r
7936fb6a 1221\r
7c6c064c
ED
1222**/\r
1223EFI_HII_HANDLE\r
1224FormSetGuidToHiiHandle (\r
1225 EFI_GUID *ComparingGuid\r
1226 )\r
1227{\r
1228 EFI_HII_HANDLE *HiiHandles;\r
7c6c064c 1229 EFI_HII_HANDLE HiiHandle;\r
07d7dbae 1230 UINTN Index;\r
7c6c064c
ED
1231\r
1232 ASSERT (ComparingGuid != NULL);\r
1233\r
1234 HiiHandle = NULL;\r
7936fb6a 1235 //\r
7c6c064c 1236 // Get all the Hii handles\r
7936fb6a 1237 //\r
7c6c064c
ED
1238 HiiHandles = HiiGetHiiHandles (NULL);\r
1239 ASSERT (HiiHandles != NULL);\r
25361615
ED
1240\r
1241 //\r
7c6c064c 1242 // Search for formset of each class type\r
25361615 1243 //\r
7c6c064c 1244 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
07d7dbae
ED
1245 if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], ComparingGuid)) {\r
1246 HiiHandle = HiiHandles[Index];\r
1247 break;\r
7c6c064c
ED
1248 }\r
1249\r
07d7dbae
ED
1250 if (HiiHandle != NULL) {\r
1251 break;\r
7c6c064c 1252 }\r
7936fb6a 1253 }\r
1254\r
7c6c064c 1255 FreePool (HiiHandles);\r
7936fb6a 1256\r
7c6c064c 1257 return HiiHandle;\r
7936fb6a 1258}\r
1259\r
1260/**\r
7c6c064c
ED
1261 check how to process the changed data in current form or form set.\r
1262\r
1263 @param Selection On input, Selection tell setup browser the information\r
1264 about the Selection, form and formset to be displayed.\r
1265 On output, Selection return the screen item that is selected\r
1266 by user.\r
7936fb6a 1267\r
7c6c064c 1268 @param Scope Data save or discard scope, form or formset.\r
7936fb6a 1269\r
7c6c064c
ED
1270 @retval TRUE Success process the changed data, will return to the parent form.\r
1271 @retval FALSE Reject to process the changed data, will stay at current form.\r
7936fb6a 1272**/\r
7c6c064c
ED
1273BOOLEAN\r
1274ProcessChangedData (\r
1275 IN OUT UI_MENU_SELECTION *Selection,\r
1276 IN BROWSER_SETTING_SCOPE Scope\r
7936fb6a 1277 )\r
1278{\r
4d4deaac
ED
1279 BOOLEAN RetValue;\r
1280 EFI_STATUS Status;\r
7936fb6a 1281\r
7c6c064c
ED
1282 RetValue = TRUE;\r
1283 switch (mFormDisplay->ConfirmDataChange()) {\r
6307a8b6 1284 case BROWSER_ACTION_DISCARD:\r
7c6c064c
ED
1285 DiscardForm (Selection->FormSet, Selection->Form, Scope);\r
1286 break;\r
d1102dba 1287\r
6307a8b6 1288 case BROWSER_ACTION_SUBMIT:\r
4d4deaac
ED
1289 Status = SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
1290 if (EFI_ERROR (Status)) {\r
1291 RetValue = FALSE;\r
1292 }\r
7c6c064c 1293 break;\r
7936fb6a 1294\r
6307a8b6 1295 case BROWSER_ACTION_NONE:\r
7c6c064c
ED
1296 RetValue = FALSE;\r
1297 break;\r
b9feb4bd 1298\r
7c6c064c
ED
1299 default:\r
1300 //\r
1301 // if Invalid value return, process same as BROWSER_ACTION_NONE.\r
1302 //\r
1303 RetValue = FALSE;\r
1304 break;\r
1305 }\r
1306\r
1307 return RetValue;\r
7936fb6a 1308}\r
1309\r
1310/**\r
7c6c064c
ED
1311 Find parent formset menu(the first menu which has different formset) for current menu.\r
1312 If not find, just return to the first menu.\r
7936fb6a 1313\r
7c6c064c 1314 @param Selection The selection info.\r
7936fb6a 1315\r
1316**/\r
7c6c064c
ED
1317VOID\r
1318FindParentFormSet (\r
1319 IN OUT UI_MENU_SELECTION *Selection\r
7936fb6a 1320 )\r
1321{\r
7c6c064c
ED
1322 FORM_ENTRY_INFO *CurrentMenu;\r
1323 FORM_ENTRY_INFO *ParentMenu;\r
25361615 1324\r
7c6c064c 1325 CurrentMenu = Selection->CurrentMenu;\r
93551a01 1326 ParentMenu = UiFindParentMenu(CurrentMenu, FormSetLevel);\r
7c6c064c
ED
1327\r
1328 if (ParentMenu != NULL) {\r
1329 CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
1330 Selection->Handle = ParentMenu->HiiHandle;\r
1331 Selection->FormId = ParentMenu->FormId;\r
1332 Selection->QuestionId = ParentMenu->QuestionId;\r
1333 } else {\r
1334 Selection->FormId = CurrentMenu->FormId;\r
1335 Selection->QuestionId = CurrentMenu->QuestionId;\r
1336 }\r
7936fb6a 1337\r
7c6c064c 1338 Selection->Statement = NULL;\r
7936fb6a 1339}\r
1340\r
1341/**\r
7c6c064c 1342 Process the goto op code, update the info in the selection structure.\r
7936fb6a 1343\r
7c6c064c
ED
1344 @param Statement The statement belong to goto op code.\r
1345 @param Selection The selection info.\r
1346\r
1347 @retval EFI_SUCCESS The menu process successfully.\r
1348 @return Other value if the process failed.\r
7936fb6a 1349**/\r
7c6c064c
ED
1350EFI_STATUS\r
1351ProcessGotoOpCode (\r
1352 IN OUT FORM_BROWSER_STATEMENT *Statement,\r
1353 IN OUT UI_MENU_SELECTION *Selection\r
7936fb6a 1354 )\r
1355{\r
7c6c064c
ED
1356 CHAR16 *StringPtr;\r
1357 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
1358 FORM_BROWSER_FORM *RefForm;\r
1359 EFI_STATUS Status;\r
1360 EFI_HII_HANDLE HiiHandle;\r
d1102dba 1361\r
7c6c064c
ED
1362 Status = EFI_SUCCESS;\r
1363 StringPtr = NULL;\r
1364 HiiHandle = NULL;\r
25361615 1365\r
b9feb4bd 1366 //\r
7c6c064c 1367 // Prepare the device path check, get the device path info first.\r
b9feb4bd 1368 //\r
7c6c064c
ED
1369 if (Statement->HiiValue.Value.ref.DevicePath != 0) {\r
1370 StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);\r
25361615 1371 }\r
b9feb4bd 1372\r
7c6c064c
ED
1373 //\r
1374 // Check whether the device path string is a valid string.\r
1375 //\r
798e4d22 1376 if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL && StringPtr[0] != L'\0') {\r
7c6c064c
ED
1377 if (Selection->Form->ModalForm) {\r
1378 return Status;\r
1379 }\r
1380\r
25361615 1381 //\r
7c6c064c 1382 // Goto another Hii Package list\r
25361615 1383 //\r
7c6c064c
ED
1384 if (mPathFromText != NULL) {\r
1385 DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);\r
1386 if (DevicePath != NULL) {\r
07d7dbae 1387 HiiHandle = DevicePathToHiiHandle (DevicePath, &Statement->HiiValue.Value.ref.FormSetGuid);\r
7c6c064c
ED
1388 FreePool (DevicePath);\r
1389 }\r
1390 FreePool (StringPtr);\r
1391 } else {\r
7936fb6a 1392 //\r
7c6c064c 1393 // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.\r
7936fb6a 1394 //\r
4d4deaac 1395 PopupErrorMessage(BROWSER_PROTOCOL_NOT_FOUND, NULL, NULL, NULL);\r
7c6c064c
ED
1396 FreePool (StringPtr);\r
1397 return Status;\r
1398 }\r
25361615 1399\r
7c6c064c
ED
1400 if (HiiHandle != Selection->Handle) {\r
1401 //\r
1402 // Goto another Formset, check for uncommitted data\r
1403 //\r
1404 if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&\r
1405 IsNvUpdateRequiredForFormSet(Selection->FormSet)) {\r
1406 if (!ProcessChangedData(Selection, FormSetLevel)) {\r
1407 return EFI_SUCCESS;\r
7936fb6a 1408 }\r
7936fb6a 1409 }\r
1410 }\r
7936fb6a 1411\r
7c6c064c
ED
1412 Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
1413 Selection->Handle = HiiHandle;\r
1414 if (Selection->Handle == NULL) {\r
1415 //\r
1416 // If target Hii Handle not found, exit current formset.\r
1417 //\r
1418 FindParentFormSet(Selection);\r
1419 return EFI_SUCCESS;\r
7936fb6a 1420 }\r
1421\r
7c6c064c
ED
1422 CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
1423 Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
1424 Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
39cde03c 1425 } else if (!IsZeroGuid (&Statement->HiiValue.Value.ref.FormSetGuid)) {\r
7c6c064c
ED
1426 if (Selection->Form->ModalForm) {\r
1427 return Status;\r
1428 }\r
1429 if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &Selection->FormSetGuid)) {\r
7936fb6a 1430 //\r
7c6c064c 1431 // Goto another Formset, check for uncommitted data\r
7936fb6a 1432 //\r
7c6c064c
ED
1433 if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&\r
1434 IsNvUpdateRequiredForFormSet(Selection->FormSet)) {\r
1435 if (!ProcessChangedData(Selection, FormSetLevel)) {\r
1436 return EFI_SUCCESS;\r
1437 }\r
7936fb6a 1438 }\r
7c6c064c 1439 }\r
7936fb6a 1440\r
7c6c064c
ED
1441 Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
1442 Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);\r
1443 if (Selection->Handle == NULL) {\r
1444 //\r
1445 // If target Hii Handle not found, exit current formset.\r
1446 //\r
1447 FindParentFormSet(Selection);\r
1448 return EFI_SUCCESS;\r
1449 }\r
7936fb6a 1450\r
7c6c064c
ED
1451 CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
1452 Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
1453 Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
1454 } else if (Statement->HiiValue.Value.ref.FormId != 0) {\r
1455 //\r
1456 // Goto another Form, check for uncommitted data\r
1457 //\r
1458 if (Statement->HiiValue.Value.ref.FormId != Selection->FormId) {\r
1459 if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm(Selection->Form))) {\r
1460 if (!ProcessChangedData (Selection, FormLevel)) {\r
1461 return EFI_SUCCESS;\r
1462 }\r
1463 }\r
1464 }\r
7936fb6a 1465\r
7c6c064c
ED
1466 RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);\r
1467 if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {\r
1468 if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {\r
1469 //\r
d1102dba 1470 // Form is suppressed.\r
7c6c064c 1471 //\r
4d4deaac 1472 PopupErrorMessage(BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);\r
7c6c064c
ED
1473 return EFI_SUCCESS;\r
1474 }\r
7936fb6a 1475 }\r
7936fb6a 1476\r
7c6c064c
ED
1477 Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
1478 Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
1479 } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {\r
1480 Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
1481 }\r
25361615 1482\r
7c6c064c 1483 return Status;\r
7936fb6a 1484}\r
1485\r
1486\r
1487/**\r
7c6c064c 1488 Process Question Config.\r
7936fb6a 1489\r
7c6c064c
ED
1490 @param Selection The UI menu selection.\r
1491 @param Question The Question to be peocessed.\r
7936fb6a 1492\r
7c6c064c
ED
1493 @retval EFI_SUCCESS Question Config process success.\r
1494 @retval Other Question Config process fail.\r
7936fb6a 1495\r
1496**/\r
1497EFI_STATUS\r
7c6c064c
ED
1498ProcessQuestionConfig (\r
1499 IN UI_MENU_SELECTION *Selection,\r
1500 IN FORM_BROWSER_STATEMENT *Question\r
7936fb6a 1501 )\r
1502{\r
7c6c064c
ED
1503 EFI_STATUS Status;\r
1504 CHAR16 *ConfigResp;\r
1505 CHAR16 *Progress;\r
7936fb6a 1506\r
7c6c064c
ED
1507 if (Question->QuestionConfig == 0) {\r
1508 return EFI_SUCCESS;\r
1509 }\r
7936fb6a 1510\r
7c6c064c
ED
1511 //\r
1512 // Get <ConfigResp>\r
1513 //\r
1514 ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);\r
1515 if (ConfigResp == NULL) {\r
1516 return EFI_NOT_FOUND;\r
40ad4b1a
ED
1517 } else if (ConfigResp[0] == L'\0') {\r
1518 return EFI_SUCCESS;\r
7c6c064c 1519 }\r
7936fb6a 1520\r
7c6c064c
ED
1521 //\r
1522 // Send config to Configuration Driver\r
1523 //\r
7248790e
ED
1524 Status = mHiiConfigRouting->RouteConfig (\r
1525 mHiiConfigRouting,\r
7c6c064c
ED
1526 ConfigResp,\r
1527 &Progress\r
1528 );\r
7936fb6a 1529\r
7c6c064c 1530 return Status;\r
7936fb6a 1531}\r
1532\r
7936fb6a 1533/**\r
1534\r
7c6c064c 1535 Process the user input data.\r
d66e6c16 1536\r
7c6c064c 1537 @param UserInput The user input data.\r
d66e6c16 1538\r
7936fb6a 1539 @retval EFI_SUCESSS This function always return successfully for now.\r
1540\r
1541**/\r
1542EFI_STATUS\r
7c6c064c 1543ProcessUserInput (\r
42645c3d 1544 IN USER_INPUT *UserInput\r
7936fb6a 1545 )\r
1546{\r
7c6c064c
ED
1547 EFI_STATUS Status;\r
1548 FORM_BROWSER_STATEMENT *Statement;\r
25361615 1549\r
42645c3d
ED
1550 Status = EFI_SUCCESS;\r
1551 Statement = NULL;\r
7936fb6a 1552\r
1553 //\r
7c6c064c 1554 // When Exit from FormDisplay function, one of the below two cases must be true.\r
7936fb6a 1555 //\r
7c6c064c 1556 ASSERT (UserInput->Action != 0 || UserInput->SelectedStatement != NULL);\r
7936fb6a 1557\r
b9feb4bd 1558 //\r
7c6c064c 1559 // Remove the last highligh question id, this id will update when show next form.\r
b9feb4bd 1560 //\r
7c6c064c 1561 gCurrentSelection->QuestionId = 0;\r
42645c3d
ED
1562 if (UserInput->SelectedStatement != NULL){\r
1563 Statement = GetBrowserStatement(UserInput->SelectedStatement);\r
1564 ASSERT (Statement != NULL);\r
1565\r
1566 //\r
1567 // This question is the current user select one,record it and later\r
1568 // show it as the highlight question.\r
1569 //\r
1570 gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;\r
1571 //\r
1572 // For statement like text, actio, it not has question id.\r
1573 // So use FakeQuestionId to save the question.\r
1574 //\r
1575 if (gCurrentSelection->CurrentMenu->QuestionId == 0) {\r
1576 mCurFakeQestId = Statement->FakeQuestionId;\r
1577 } else {\r
1578 mCurFakeQestId = 0;\r
1579 }\r
1580 }\r
7936fb6a 1581\r
7c6c064c
ED
1582 //\r
1583 // First process the Action field in USER_INPUT.\r
1584 //\r
1585 if (UserInput->Action != 0) {\r
1586 Status = ProcessAction (UserInput->Action, UserInput->DefaultId);\r
7c6c064c 1587 gCurrentSelection->Statement = NULL;\r
7c6c064c 1588 } else {\r
7c6c064c 1589 ASSERT (Statement != NULL);\r
7c6c064c 1590 gCurrentSelection->Statement = Statement;\r
7c6c064c
ED
1591 switch (Statement->Operand) {\r
1592 case EFI_IFR_REF_OP:\r
1593 Status = ProcessGotoOpCode(Statement, gCurrentSelection);\r
1594 break;\r
d1102dba 1595\r
7c6c064c
ED
1596 case EFI_IFR_ACTION_OP:\r
1597 //\r
1598 // Process the Config string <ConfigResp>\r
1599 //\r
1600 Status = ProcessQuestionConfig (gCurrentSelection, Statement);\r
1601 break;\r
d1102dba 1602\r
7c6c064c 1603 case EFI_IFR_RESET_BUTTON_OP:\r
7936fb6a 1604 //\r
7c6c064c 1605 // Reset Question to default value specified by DefaultId\r
7936fb6a 1606 //\r
787fc2a6 1607 Status = ExtractDefault (gCurrentSelection->FormSet, NULL, Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE, FALSE);\r
892eccc8 1608 UpdateStatementStatus (gCurrentSelection->FormSet, NULL, FormSetLevel);\r
7c6c064c
ED
1609 break;\r
1610\r
1611 default:\r
1612 switch (Statement->Operand) {\r
1613 case EFI_IFR_STRING_OP:\r
1614 DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);\r
1615 Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;\r
1616 CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);\r
1617 FreePool (UserInput->InputValue.Buffer);\r
1618 break;\r
1619\r
1620 case EFI_IFR_PASSWORD_OP:\r
1621 if (UserInput->InputValue.Buffer == NULL) {\r
1622 //\r
1623 // User not input new password, just return.\r
1624 //\r
1625 break;\r
1626 }\r
8b0fc5c1 1627\r
7c6c064c
ED
1628 DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);\r
1629 Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;\r
1630 CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);\r
a275df8f 1631 ZeroMem (UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);\r
7c6c064c 1632 FreePool (UserInput->InputValue.Buffer);\r
8b0fc5c1 1633 //\r
7c6c064c 1634 // Two password match, send it to Configuration Driver\r
8b0fc5c1 1635 //\r
7c6c064c
ED
1636 if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
1637 PasswordCheck (NULL, UserInput->SelectedStatement, (CHAR16 *) Statement->BufferValue);\r
1638 //\r
1639 // Clean the value after saved it.\r
1640 //\r
1641 ZeroMem (Statement->BufferValue, (UINTN) UserInput->InputValue.BufferLen);\r
1642 HiiSetString (gCurrentSelection->FormSet->HiiHandle, Statement->HiiValue.Value.string, (CHAR16*)Statement->BufferValue, NULL);\r
1643 } else {\r
1644 SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);\r
1645 }\r
1646 break;\r
1647\r
1648 case EFI_IFR_ORDERED_LIST_OP:\r
1649 CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, UserInput->InputValue.BufferLen);\r
1650 break;\r
1651\r
1652 default:\r
1653 CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));\r
1654 break;\r
1655 }\r
7c6c064c 1656 break;\r
7936fb6a 1657 }\r
7936fb6a 1658 }\r
1659\r
7936fb6a 1660 return Status;\r
1661}\r
1662\r
1663/**\r
7936fb6a 1664\r
7c6c064c 1665 Display form and wait for user to select one menu option, then return it.\r
7936fb6a 1666\r
7c6c064c 1667 @retval EFI_SUCESSS This function always return successfully for now.\r
48a9d5f7
LG
1668\r
1669**/\r
7c6c064c
ED
1670EFI_STATUS\r
1671DisplayForm (\r
48a9d5f7
LG
1672 VOID\r
1673 )\r
1674{\r
7c6c064c
ED
1675 EFI_STATUS Status;\r
1676 USER_INPUT UserInput;\r
1677 FORM_ENTRY_INFO *CurrentMenu;\r
48a9d5f7 1678\r
7c6c064c 1679 ZeroMem (&UserInput, sizeof (USER_INPUT));\r
48a9d5f7
LG
1680\r
1681 //\r
7c6c064c 1682 // Update the menu history data.\r
48a9d5f7 1683 //\r
7c6c064c
ED
1684 CurrentMenu = UiFindMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid, gCurrentSelection->FormId);\r
1685 if (CurrentMenu == NULL) {\r
48a9d5f7 1686 //\r
7c6c064c 1687 // Current menu not found, add it to the menu tree\r
25361615 1688 //\r
7c6c064c
ED
1689 CurrentMenu = UiAddMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid,\r
1690 gCurrentSelection->FormId, gCurrentSelection->QuestionId);\r
1691 ASSERT (CurrentMenu != NULL);\r
1692 }\r
4d4deaac
ED
1693\r
1694 //\r
1695 // Back up the form view history data for this form.\r
1696 //\r
1697 UiCopyMenuList(&gCurrentSelection->Form->FormViewListHead, &mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
1698\r
7c6c064c 1699 gCurrentSelection->CurrentMenu = CurrentMenu;\r
48a9d5f7 1700\r
7c6c064c 1701 if (gCurrentSelection->QuestionId == 0) {\r
48a9d5f7 1702 //\r
7c6c064c 1703 // Highlight not specified, fetch it from cached menu\r
48a9d5f7 1704 //\r
7c6c064c 1705 gCurrentSelection->QuestionId = CurrentMenu->QuestionId;\r
48a9d5f7 1706 }\r
25361615 1707\r
7c6c064c
ED
1708 Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form);\r
1709 if (EFI_ERROR (Status)) {\r
1710 return Status;\r
b9feb4bd 1711 }\r
7936fb6a 1712\r
7c6c064c 1713 UpdateDisplayFormData ();\r
25361615 1714\r
4d4deaac 1715 ASSERT (gDisplayFormData.BrowserStatus == BROWSER_SUCCESS);\r
7c6c064c 1716 Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput);\r
42645c3d 1717 if (EFI_ERROR (Status)) {\r
7c6c064c
ED
1718 FreeDisplayFormData();\r
1719 return Status;\r
1720 }\r
25361615 1721\r
034a3b4f
GY
1722 CheckConfigAccess(gCurrentSelection->FormSet);\r
1723\r
42645c3d 1724 Status = ProcessUserInput (&UserInput);\r
7c6c064c 1725 FreeDisplayFormData();\r
7c6c064c 1726 return Status;\r
7936fb6a 1727}\r
1728\r
1729/**\r
1730 Functions which are registered to receive notification of\r
1731 database events have this prototype. The actual event is encoded\r
1732 in NotifyType. The following table describes how PackageType,\r
1733 PackageGuid, Handle, and Package are used for each of the\r
1734 notification types.\r
1735\r
1736 @param PackageType Package type of the notification.\r
1737\r
1738 @param PackageGuid If PackageType is\r
1739 EFI_HII_PACKAGE_TYPE_GUID, then this is\r
1740 the pointer to the GUID from the Guid\r
1741 field of EFI_HII_PACKAGE_GUID_HEADER.\r
1742 Otherwise, it must be NULL.\r
1743\r
1744 @param Package Points to the package referred to by the\r
1745 notification Handle The handle of the package\r
1746 list which contains the specified package.\r
1747\r
1748 @param Handle The HII handle.\r
1749\r
1750 @param NotifyType The type of change concerning the\r
1751 database. See\r
1752 EFI_HII_DATABASE_NOTIFY_TYPE.\r
1753\r
1754**/\r
1755EFI_STATUS\r
6d3ea23f 1756EFIAPI\r
7936fb6a 1757FormUpdateNotify (\r
1758 IN UINT8 PackageType,\r
1759 IN CONST EFI_GUID *PackageGuid,\r
1760 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
1761 IN EFI_HII_HANDLE Handle,\r
1762 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
1763 )\r
1764{\r
1765 mHiiPackageListUpdated = TRUE;\r
365fdb0f 1766 mDynamicFormUpdated = TRUE;\r
7936fb6a 1767\r
1768 return EFI_SUCCESS;\r
1769}\r
1770\r
b18e7050 1771/**\r
7c6c064c 1772 Update the NV flag info for this form set.\r
b18e7050
ED
1773\r
1774 @param FormSet FormSet data structure.\r
1775\r
b18e7050 1776**/\r
7c6c064c
ED
1777BOOLEAN\r
1778IsNvUpdateRequiredForFormSet (\r
b18e7050
ED
1779 IN FORM_BROWSER_FORMSET *FormSet\r
1780 )\r
1781{\r
1782 LIST_ENTRY *Link;\r
1783 FORM_BROWSER_FORM *Form;\r
7c6c064c
ED
1784 BOOLEAN RetVal;\r
1785\r
1786 //\r
1787 // Not finished question initialization, return FALSE.\r
1788 //\r
1789 if (!FormSet->QuestionInited) {\r
1790 return FALSE;\r
1791 }\r
1792\r
1793 RetVal = FALSE;\r
b18e7050
ED
1794\r
1795 Link = GetFirstNode (&FormSet->FormListHead);\r
1796 while (!IsNull (&FormSet->FormListHead, Link)) {\r
1797 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
1798\r
7c6c064c
ED
1799 RetVal = IsNvUpdateRequiredForForm(Form);\r
1800 if (RetVal) {\r
1801 break;\r
b9feb4bd
ED
1802 }\r
1803\r
25361615 1804 Link = GetNextNode (&FormSet->FormListHead, Link);\r
b9feb4bd
ED
1805 }\r
1806\r
7c6c064c
ED
1807 return RetVal;\r
1808}\r
1809\r
1810/**\r
1811 Update the NvUpdateRequired flag for a form.\r
1812\r
1813 @param Form Form data structure.\r
1814\r
1815**/\r
1816BOOLEAN\r
1817IsNvUpdateRequiredForForm (\r
1818 IN FORM_BROWSER_FORM *Form\r
1819 )\r
1820{\r
1821 LIST_ENTRY *Link;\r
1822 FORM_BROWSER_STATEMENT *Statement;\r
1823\r
1824 Link = GetFirstNode (&Form->StatementListHead);\r
1825 while (!IsNull (&Form->StatementListHead, Link)) {\r
1826 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1827\r
1828 if (Statement->ValueChanged) {\r
1829 return TRUE;\r
1830 }\r
1831\r
1832 Link = GetNextNode (&Form->StatementListHead, Link);\r
1833 }\r
1834\r
b18e7050
ED
1835 return FALSE;\r
1836}\r
1837\r
b18e7050
ED
1838/**\r
1839 Find menu which will show next time.\r
1840\r
1841 @param Selection On input, Selection tell setup browser the information\r
1842 about the Selection, form and formset to be displayed.\r
1843 On output, Selection return the screen item that is selected\r
1844 by user.\r
d1102dba 1845 @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.\r
7c6c064c 1846 else, we need to exit current formset.\r
d1102dba 1847\r
7c6c064c
ED
1848 @retval TRUE Exit current form.\r
1849 @retval FALSE User press ESC and keep in current form.\r
b18e7050
ED
1850**/\r
1851BOOLEAN\r
1852FindNextMenu (\r
7c6c064c 1853 IN OUT UI_MENU_SELECTION *Selection,\r
93551a01 1854 IN BROWSER_SETTING_SCOPE SettingLevel\r
b18e7050
ED
1855 )\r
1856{\r
7c6c064c
ED
1857 FORM_ENTRY_INFO *CurrentMenu;\r
1858 FORM_ENTRY_INFO *ParentMenu;\r
1859 BROWSER_SETTING_SCOPE Scope;\r
d1102dba 1860\r
b18e7050 1861 CurrentMenu = Selection->CurrentMenu;\r
7c6c064c 1862 Scope = FormSetLevel;\r
b18e7050 1863\r
93551a01
ED
1864 ParentMenu = UiFindParentMenu(CurrentMenu, SettingLevel);\r
1865 while (ParentMenu != NULL && !ValidateHiiHandle(ParentMenu->HiiHandle)) {\r
1866 ParentMenu = UiFindParentMenu(ParentMenu, SettingLevel);\r
1867 }\r
25361615 1868\r
93551a01
ED
1869 if (ParentMenu != NULL) {\r
1870 if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
1871 Scope = FormLevel;\r
7c6c064c
ED
1872 } else {\r
1873 Scope = FormSetLevel;\r
b18e7050 1874 }\r
25361615
ED
1875 }\r
1876\r
b9feb4bd 1877 //\r
7c6c064c 1878 // Form Level Check whether the data is changed.\r
b9feb4bd 1879 //\r
7c6c064c
ED
1880 if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm (Selection->Form)) ||\r
1881 (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet(Selection->FormSet) && Scope == FormSetLevel)) {\r
4d4deaac 1882 if (!ProcessChangedData(Selection, gBrowserSettingScope)) {\r
25361615
ED
1883 return FALSE;\r
1884 }\r
7c6c064c 1885 }\r
b9feb4bd 1886\r
7c6c064c
ED
1887 if (ParentMenu != NULL) {\r
1888 //\r
1889 // ParentMenu is found. Then, go to it.\r
1890 //\r
1891 if (Scope == FormLevel) {\r
1892 Selection->Action = UI_ACTION_REFRESH_FORM;\r
25361615 1893 } else {\r
7c6c064c
ED
1894 Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
1895 CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
1896 Selection->Handle = ParentMenu->HiiHandle;\r
25361615 1897 }\r
25361615 1898\r
7c6c064c
ED
1899 Selection->Statement = NULL;\r
1900\r
1901 Selection->FormId = ParentMenu->FormId;\r
1902 Selection->QuestionId = ParentMenu->QuestionId;\r
1903\r
1904 //\r
1905 // Clear highlight record for this menu\r
1906 //\r
25361615 1907 CurrentMenu->QuestionId = 0;\r
7c6c064c 1908 return FALSE;\r
25361615
ED
1909 }\r
1910\r
7c6c064c
ED
1911 //\r
1912 // Current in root page, exit the SendForm\r
1913 //\r
25361615 1914 Selection->Action = UI_ACTION_EXIT;\r
7c6c064c 1915\r
b18e7050
ED
1916 return TRUE;\r
1917}\r
1918\r
f2e7732e
ED
1919/**\r
1920 Reconnect the controller.\r
1921\r
1922 @param DriverHandle The controller handle which need to be reconnect.\r
1923\r
1924 @retval TRUE do the reconnect behavior success.\r
1925 @retval FALSE do the reconnect behavior failed.\r
d1102dba 1926\r
f2e7732e
ED
1927**/\r
1928BOOLEAN\r
1929ReconnectController (\r
1930 IN EFI_HANDLE DriverHandle\r
1931 )\r
1932{\r
1933 EFI_STATUS Status;\r
1934\r
1935 Status = gBS->DisconnectController(DriverHandle, NULL, NULL);\r
1936 if (!EFI_ERROR (Status)) {\r
1937 Status = gBS->ConnectController(DriverHandle, NULL, NULL, TRUE);\r
1938 }\r
1939\r
1940 return Status == EFI_SUCCESS;\r
1941}\r
1942\r
b18e7050
ED
1943/**\r
1944 Call the call back function for the question and process the return action.\r
1945\r
1946 @param Selection On input, Selection tell setup browser the information\r
1947 about the Selection, form and formset to be displayed.\r
1948 On output, Selection return the screen item that is selected\r
1949 by user.\r
798e4d22
ED
1950 @param FormSet The formset this question belong to.\r
1951 @param Form The form this question belong to.\r
b18e7050
ED
1952 @param Question The Question which need to call.\r
1953 @param Action The action request.\r
1954 @param SkipSaveOrDiscard Whether skip save or discard action.\r
1955\r
0a18956d
GL
1956 @retval EFI_SUCCESS The call back function executes successfully.\r
1957 @return Other value if the call back function failed to execute.\r
b18e7050 1958**/\r
d1102dba 1959EFI_STATUS\r
b18e7050
ED
1960ProcessCallBackFunction (\r
1961 IN OUT UI_MENU_SELECTION *Selection,\r
798e4d22
ED
1962 IN FORM_BROWSER_FORMSET *FormSet,\r
1963 IN FORM_BROWSER_FORM *Form,\r
b18e7050
ED
1964 IN FORM_BROWSER_STATEMENT *Question,\r
1965 IN EFI_BROWSER_ACTION Action,\r
1966 IN BOOLEAN SkipSaveOrDiscard\r
1967 )\r
1968{\r
1969 EFI_STATUS Status;\r
fc2e7502 1970 EFI_STATUS InternalStatus;\r
b18e7050
ED
1971 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
1972 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
1973 EFI_HII_VALUE *HiiValue;\r
1974 EFI_IFR_TYPE_VALUE *TypeValue;\r
1975 FORM_BROWSER_STATEMENT *Statement;\r
1976 BOOLEAN SubmitFormIsRequired;\r
b18e7050
ED
1977 BOOLEAN DiscardFormIsRequired;\r
1978 BOOLEAN NeedExit;\r
1979 LIST_ENTRY *Link;\r
48a9d5f7 1980 BROWSER_SETTING_SCOPE SettingLevel;\r
e6cc2ab3
ED
1981 EFI_IFR_TYPE_VALUE BackUpValue;\r
1982 UINT8 *BackUpBuffer;\r
061d5462 1983 CHAR16 *NewString;\r
b18e7050 1984\r
798e4d22 1985 ConfigAccess = FormSet->ConfigAccess;\r
b18e7050 1986 SubmitFormIsRequired = FALSE;\r
48a9d5f7 1987 SettingLevel = FormSetLevel;\r
b18e7050
ED
1988 DiscardFormIsRequired = FALSE;\r
1989 NeedExit = FALSE;\r
1990 Status = EFI_SUCCESS;\r
1991 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
e6cc2ab3 1992 BackUpBuffer = NULL;\r
b18e7050
ED
1993\r
1994 if (ConfigAccess == NULL) {\r
1995 return EFI_SUCCESS;\r
1996 }\r
1997\r
798e4d22
ED
1998 Link = GetFirstNode (&Form->StatementListHead);\r
1999 while (!IsNull (&Form->StatementListHead, Link)) {\r
b18e7050 2000 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
798e4d22 2001 Link = GetNextNode (&Form->StatementListHead, Link);\r
b18e7050
ED
2002\r
2003 //\r
2004 // if Question != NULL, only process the question. Else, process all question in this form.\r
2005 //\r
2006 if ((Question != NULL) && (Statement != Question)) {\r
2007 continue;\r
2008 }\r
d1102dba 2009\r
b18e7050
ED
2010 if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
2011 continue;\r
2012 }\r
2013\r
2014 //\r
2015 // Check whether Statement is disabled.\r
2016 //\r
31585af4 2017 if (Statement->Expression != NULL) {\r
798e4d22 2018 if (EvaluateExpressionList(Statement->Expression, TRUE, FormSet, Form) == ExpressDisable) {\r
b18e7050
ED
2019 continue;\r
2020 }\r
2021 }\r
2022\r
2023 HiiValue = &Statement->HiiValue;\r
2024 TypeValue = &HiiValue->Value;\r
2025 if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
2026 //\r
2027 // For OrderedList, passing in the value buffer to Callback()\r
2028 //\r
2029 TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
2030 }\r
e6cc2ab3
ED
2031\r
2032 //\r
2033 // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.\r
2034 //\r
2035 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
2036 if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
04722cfa 2037 BackUpBuffer = AllocateCopyPool(Statement->StorageWidth, Statement->BufferValue);\r
523f48e7 2038 ASSERT (BackUpBuffer != NULL);\r
e6cc2ab3
ED
2039 } else {\r
2040 CopyMem (&BackUpValue, &HiiValue->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
2041 }\r
2042 }\r
2043\r
b18e7050
ED
2044 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
2045 Status = ConfigAccess->Callback (\r
2046 ConfigAccess,\r
2047 Action,\r
2048 Statement->QuestionId,\r
2049 HiiValue->Type,\r
2050 TypeValue,\r
2051 &ActionRequest\r
2052 );\r
2053 if (!EFI_ERROR (Status)) {\r
bfae1330
ED
2054 //\r
2055 // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue\r
2056 //\r
2057 if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
2058 NewString = GetToken (Statement->HiiValue.Value.string, FormSet->HiiHandle);\r
2059 ASSERT (NewString != NULL);\r
2060\r
2061 ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
2062 if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
05b2f9c9 2063 ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
bfae1330
ED
2064 CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
2065 } else {\r
2066 CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
2067 }\r
2068 FreePool (NewString);\r
2069 }\r
2070\r
3a4e7a3e
ED
2071 //\r
2072 // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.\r
2073 //\r
bfae1330
ED
2074 switch (Action) {\r
2075 case EFI_BROWSER_ACTION_CHANGED:\r
3a4e7a3e
ED
2076 switch (ActionRequest) {\r
2077 case EFI_BROWSER_ACTION_REQUEST_RESET:\r
98970c60 2078 DiscardFormIsRequired = TRUE;\r
b2dcae4c
BD
2079 gResetRequiredFormLevel = TRUE;\r
2080 gResetRequiredSystemLevel = TRUE;\r
7c6c064c 2081 NeedExit = TRUE;\r
3a4e7a3e 2082 break;\r
b18e7050 2083\r
3a4e7a3e
ED
2084 case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
2085 SubmitFormIsRequired = TRUE;\r
7c6c064c 2086 NeedExit = TRUE;\r
3a4e7a3e 2087 break;\r
b18e7050 2088\r
3a4e7a3e 2089 case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
05b9f4cf 2090 DiscardFormIsRequired = TRUE;\r
7c6c064c 2091 NeedExit = TRUE;\r
3a4e7a3e 2092 break;\r
b18e7050 2093\r
3a4e7a3e
ED
2094 case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:\r
2095 SubmitFormIsRequired = TRUE;\r
2096 SettingLevel = FormLevel;\r
2097 NeedExit = TRUE;\r
2098 break;\r
b18e7050 2099\r
3a4e7a3e
ED
2100 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:\r
2101 DiscardFormIsRequired = TRUE;\r
7c6c064c 2102 SettingLevel = FormLevel;\r
3a4e7a3e
ED
2103 NeedExit = TRUE;\r
2104 break;\r
b18e7050 2105\r
3a4e7a3e
ED
2106 case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY:\r
2107 SubmitFormIsRequired = TRUE;\r
2108 SettingLevel = FormLevel;\r
2109 break;\r
b18e7050 2110\r
3a4e7a3e
ED
2111 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD:\r
2112 DiscardFormIsRequired = TRUE;\r
2113 SettingLevel = FormLevel;\r
2114 break;\r
b18e7050 2115\r
f2e7732e
ED
2116 case EFI_BROWSER_ACTION_REQUEST_RECONNECT:\r
2117 gCallbackReconnect = TRUE;\r
2118 break;\r
2119\r
3a4e7a3e
ED
2120 default:\r
2121 break;\r
2122 }\r
bfae1330 2123 break;\r
061d5462 2124\r
bfae1330
ED
2125 case EFI_BROWSER_ACTION_CHANGING:\r
2126 //\r
2127 // Do the question validation.\r
2128 //\r
2129 Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
2130 if (!EFI_ERROR (Status)) {\r
e6557276
DB
2131 //\r
2132 //check whether the question value changed compared with edit buffer before updating edit buffer\r
2133 // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
2134 //\r
2135 IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
bfae1330 2136 //\r
d1102dba 2137 // According the spec, return value from call back of "changing" and\r
bfae1330
ED
2138 // "retrieve" should update to the question's temp buffer.\r
2139 //\r
2140 SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
061d5462 2141 }\r
bfae1330 2142 break;\r
061d5462 2143\r
bfae1330
ED
2144 case EFI_BROWSER_ACTION_RETRIEVE:\r
2145 //\r
d1102dba 2146 // According the spec, return value from call back of "changing" and\r
bfae1330
ED
2147 // "retrieve" should update to the question's temp buffer.\r
2148 //\r
798e4d22 2149 SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
bfae1330
ED
2150 break;\r
2151\r
2152 default:\r
2153 break;\r
8ca6180f 2154 }\r
c4042207 2155 } else {\r
e6cc2ab3 2156 //\r
d1102dba
LG
2157 // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,\r
2158 // then the browser will use the value passed to Callback() and ignore the\r
2159 // value returned by Callback().\r
e6cc2ab3
ED
2160 //\r
2161 if (Action == EFI_BROWSER_ACTION_CHANGING && Status == EFI_UNSUPPORTED) {\r
2162 if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
04722cfa 2163 CopyMem (Statement->BufferValue, BackUpBuffer, Statement->StorageWidth);\r
e6cc2ab3
ED
2164 } else {\r
2165 CopyMem (&HiiValue->Value, &BackUpValue, sizeof (EFI_IFR_TYPE_VALUE));\r
2166 }\r
d1102dba 2167\r
bfae1330
ED
2168 //\r
2169 // Do the question validation.\r
2170 //\r
fc2e7502
ED
2171 InternalStatus = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
2172 if (!EFI_ERROR (InternalStatus)) {\r
e6557276
DB
2173 //\r
2174 //check whether the question value changed compared with edit buffer before updating edit buffer\r
2175 // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
2176 //\r
2177 IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
bfae1330
ED
2178 SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
2179 }\r
e6cc2ab3
ED
2180 }\r
2181\r
b18e7050 2182 //\r
d1102dba 2183 // According the spec, return fail from call back of "changing" and\r
c4042207 2184 // "retrieve", should restore the question's value.\r
b18e7050 2185 //\r
c792e5b8
ED
2186 if (Action == EFI_BROWSER_ACTION_CHANGING && Status != EFI_UNSUPPORTED) {\r
2187 if (Statement->Storage != NULL) {\r
2188 GetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
2189 } else if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
2190 ProcessCallBackFunction (Selection, FormSet, Form, Question, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
2191 }\r
2192 }\r
2193\r
2194 if (Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
798e4d22 2195 GetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
c4042207
ED
2196 }\r
2197\r
2198 if (Status == EFI_UNSUPPORTED) {\r
2199 //\r
2200 // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
2201 //\r
2202 Status = EFI_SUCCESS;\r
2203 }\r
b18e7050 2204 }\r
e6cc2ab3
ED
2205\r
2206 if (BackUpBuffer != NULL) {\r
2207 FreePool (BackUpBuffer);\r
2208 }\r
93551a01
ED
2209\r
2210 //\r
2211 // If Question != NULL, means just process one question\r
2212 // and if code reach here means this question has finished\r
2213 // processing, so just break.\r
2214 //\r
2215 if (Question != NULL) {\r
2216 break;\r
2217 }\r
b18e7050
ED
2218 }\r
2219\r
f2e7732e
ED
2220 if (gCallbackReconnect && (EFI_BROWSER_ACTION_CHANGED == Action)) {\r
2221 //\r
2222 // Confirm changes with user first.\r
2223 //\r
2224 if (IsNvUpdateRequiredForFormSet(FormSet)) {\r
2225 if (BROWSER_ACTION_DISCARD == PopupErrorMessage(BROWSER_RECONNECT_SAVE_CHANGES, NULL, NULL, NULL)) {\r
2226 gCallbackReconnect = FALSE;\r
2227 DiscardFormIsRequired = TRUE;\r
2228 } else {\r
2229 SubmitFormIsRequired = TRUE;\r
2230 }\r
2231 } else {\r
2232 PopupErrorMessage(BROWSER_RECONNECT_REQUIRED, NULL, NULL, NULL);\r
2233 }\r
2234\r
2235 //\r
2236 // Exit current formset before do the reconnect.\r
2237 //\r
2238 NeedExit = TRUE;\r
2239 SettingLevel = FormSetLevel;\r
2240 }\r
2241\r
b18e7050 2242 if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
798e4d22 2243 SubmitForm (FormSet, Form, SettingLevel);\r
b18e7050
ED
2244 }\r
2245\r
2246 if (DiscardFormIsRequired && !SkipSaveOrDiscard) {\r
798e4d22 2247 DiscardForm (FormSet, Form, SettingLevel);\r
b18e7050
ED
2248 }\r
2249\r
2250 if (NeedExit) {\r
7c6c064c 2251 FindNextMenu (Selection, SettingLevel);\r
b18e7050
ED
2252 }\r
2253\r
2254 return Status;\r
2255}\r
2256\r
9776099f
ED
2257/**\r
2258 Call the retrieve type call back function for one question to get the initialize data.\r
d1102dba
LG
2259\r
2260 This function only used when in the initialize stage, because in this stage, the\r
9776099f
ED
2261 Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.\r
2262\r
2263 @param ConfigAccess The config access protocol produced by the hii driver.\r
2264 @param Statement The Question which need to call.\r
061d5462 2265 @param FormSet The formset this question belong to.\r
9776099f 2266\r
0a18956d
GL
2267 @retval EFI_SUCCESS The call back function executes successfully.\r
2268 @return Other value if the call back function failed to execute.\r
9776099f 2269**/\r
d1102dba 2270EFI_STATUS\r
9776099f
ED
2271ProcessRetrieveForQuestion (\r
2272 IN EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess,\r
061d5462
ED
2273 IN FORM_BROWSER_STATEMENT *Statement,\r
2274 IN FORM_BROWSER_FORMSET *FormSet\r
9776099f
ED
2275 )\r
2276{\r
2277 EFI_STATUS Status;\r
2278 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
2279 EFI_HII_VALUE *HiiValue;\r
2280 EFI_IFR_TYPE_VALUE *TypeValue;\r
061d5462 2281 CHAR16 *NewString;\r
9776099f
ED
2282\r
2283 Status = EFI_SUCCESS;\r
2284 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
70f1d5e7
ED
2285\r
2286 if (((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) || ConfigAccess == NULL) {\r
9776099f
ED
2287 return EFI_UNSUPPORTED;\r
2288 }\r
2289\r
2290 HiiValue = &Statement->HiiValue;\r
2291 TypeValue = &HiiValue->Value;\r
2292 if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
2293 //\r
2294 // For OrderedList, passing in the value buffer to Callback()\r
2295 //\r
2296 TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
2297 }\r
d1102dba 2298\r
9776099f
ED
2299 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
2300 Status = ConfigAccess->Callback (\r
2301 ConfigAccess,\r
2302 EFI_BROWSER_ACTION_RETRIEVE,\r
2303 Statement->QuestionId,\r
2304 HiiValue->Type,\r
2305 TypeValue,\r
2306 &ActionRequest\r
2307 );\r
061d5462
ED
2308 if (!EFI_ERROR (Status) && HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
2309 NewString = GetToken (Statement->HiiValue.Value.string, FormSet->HiiHandle);\r
2310 ASSERT (NewString != NULL);\r
2311\r
2312 ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
2313 if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
05b2f9c9 2314 ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
061d5462
ED
2315 CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
2316 } else {\r
2317 CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
2318 }\r
2319 FreePool (NewString);\r
2320 }\r
2321\r
9776099f
ED
2322 return Status;\r
2323}\r
2324\r
7936fb6a 2325/**\r
2326 The worker function that send the displays to the screen. On output,\r
2327 the selection made by user is returned.\r
2328\r
2329 @param Selection On input, Selection tell setup browser the information\r
2330 about the Selection, form and formset to be displayed.\r
2331 On output, Selection return the screen item that is selected\r
2332 by user.\r
2333\r
2334 @retval EFI_SUCCESS The page is displayed successfully.\r
2335 @return Other value if the page failed to be diplayed.\r
2336\r
2337**/\r
2338EFI_STATUS\r
2339SetupBrowser (\r
2340 IN OUT UI_MENU_SELECTION *Selection\r
2341 )\r
2342{\r
2343 EFI_STATUS Status;\r
2344 LIST_ENTRY *Link;\r
7936fb6a 2345 EFI_HANDLE NotifyHandle;\r
7936fb6a 2346 FORM_BROWSER_STATEMENT *Statement;\r
2347 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
2348\r
5adb8db7 2349 ConfigAccess = Selection->FormSet->ConfigAccess;\r
7936fb6a 2350\r
2351 //\r
2352 // Register notify for Form package update\r
2353 //\r
2354 Status = mHiiDatabase->RegisterPackageNotify (\r
2355 mHiiDatabase,\r
8d00a0f1 2356 EFI_HII_PACKAGE_FORMS,\r
7936fb6a 2357 NULL,\r
2358 FormUpdateNotify,\r
2359 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
2360 &NotifyHandle\r
2361 );\r
2362 if (EFI_ERROR (Status)) {\r
2363 return Status;\r
2364 }\r
2365\r
d66e6c16 2366 //\r
2367 // Initialize current settings of Questions in this FormSet\r
2368 //\r
7c6c064c 2369 InitializeCurrentSetting (Selection->FormSet);\r
b9feb4bd
ED
2370\r
2371 //\r
7c6c064c 2372 // Initilize Action field.\r
b9feb4bd 2373 //\r
7c6c064c
ED
2374 Selection->Action = UI_ACTION_REFRESH_FORM;\r
2375\r
2376 //\r
2377 // Clean the mCurFakeQestId value is formset refreshed.\r
2378 //\r
2379 mCurFakeQestId = 0;\r
48a9d5f7 2380\r
7936fb6a 2381 do {\r
00d1c2a3
CS
2382\r
2383 //\r
2384 // Reset Status to prevent the next break from returning incorrect error status.\r
2385 //\r
2386 Status = EFI_SUCCESS;\r
2387\r
54f8fc6d
ED
2388 //\r
2389 // IFR is updated, force to reparse the IFR binary\r
d1102dba 2390 // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and\r
93551a01 2391 // EFI_BROWSER_ACTION_RETRIEVE, so code place here.\r
54f8fc6d
ED
2392 //\r
2393 if (mHiiPackageListUpdated) {\r
2394 Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
2395 mHiiPackageListUpdated = FALSE;\r
2396 break;\r
2397 }\r
2398\r
7936fb6a 2399 //\r
2400 // Initialize Selection->Form\r
2401 //\r
2402 if (Selection->FormId == 0) {\r
2403 //\r
2404 // Zero FormId indicates display the first Form in a FormSet\r
2405 //\r
2406 Link = GetFirstNode (&Selection->FormSet->FormListHead);\r
2407\r
2408 Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
2409 Selection->FormId = Selection->Form->FormId;\r
2410 } else {\r
2411 Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);\r
2412 }\r
2413\r
0a1147ed
LG
2414 if (Selection->Form == NULL) {\r
2415 //\r
2416 // No Form to display\r
2417 //\r
13ad1def
LG
2418 Status = EFI_NOT_FOUND;\r
2419 goto Done;\r
0a1147ed
LG
2420 }\r
2421\r
0c66bc76
LG
2422 //\r
2423 // Check Form is suppressed.\r
2424 //\r
2425 if (Selection->Form->SuppressExpression != NULL) {\r
31585af4 2426 if (EvaluateExpressionList(Selection->Form->SuppressExpression, TRUE, Selection->FormSet, Selection->Form) == ExpressSuppress) {\r
0c66bc76 2427 //\r
d1102dba 2428 // Form is suppressed.\r
0c66bc76 2429 //\r
4d4deaac 2430 PopupErrorMessage(BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);\r
13ad1def
LG
2431 Status = EFI_NOT_FOUND;\r
2432 goto Done;\r
0c66bc76
LG
2433 }\r
2434 }\r
5adb8db7 2435\r
5adb8db7
LG
2436 //\r
2437 // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN\r
2438 // for each question with callback flag.\r
2439 // New form may be the first form, or the different form after another form close.\r
2440 //\r
70f1d5e7 2441 if (((Selection->Handle != mCurrentHiiHandle) ||\r
13ad1def
LG
2442 (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
2443 (Selection->FormId != mCurrentFormId))) {\r
6fd184d0
ED
2444 //\r
2445 // Update Retrieve flag.\r
2446 //\r
2447 mFinishRetrieveCall = FALSE;\r
2448\r
13ad1def
LG
2449 //\r
2450 // Keep current form information\r
2451 //\r
2452 mCurrentHiiHandle = Selection->Handle;\r
2453 CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
2454 mCurrentFormId = Selection->FormId;\r
2455\r
70f1d5e7 2456 if (ConfigAccess != NULL) {\r
6fd184d0 2457 Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);\r
70f1d5e7
ED
2458 if (EFI_ERROR (Status)) {\r
2459 goto Done;\r
2460 }\r
b18e7050 2461\r
70f1d5e7 2462 //\r
93551a01 2463 // IFR is updated during callback of EFI_BROWSER_ACTION_FORM_OPEN, force to reparse the IFR binary\r
70f1d5e7
ED
2464 //\r
2465 if (mHiiPackageListUpdated) {\r
2466 Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
2467 mHiiPackageListUpdated = FALSE;\r
2468 break;\r
2469 }\r
5adb8db7
LG
2470 }\r
2471 }\r
2472\r
7936fb6a 2473 //\r
2474 // Load Questions' Value for display\r
2475 //\r
eccfeab1 2476 Status = LoadFormSetConfig (Selection, Selection->FormSet);\r
7936fb6a 2477 if (EFI_ERROR (Status)) {\r
13ad1def 2478 goto Done;\r
7936fb6a 2479 }\r
2480\r
6fd184d0
ED
2481 if (!mFinishRetrieveCall) {\r
2482 //\r
2483 // Finish call RETRIEVE callback for this form.\r
2484 //\r
2485 mFinishRetrieveCall = TRUE;\r
798e4d22 2486\r
6fd184d0
ED
2487 if (ConfigAccess != NULL) {\r
2488 Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
2489 if (EFI_ERROR (Status)) {\r
2490 goto Done;\r
2491 }\r
2492\r
2493 //\r
2494 // IFR is updated during callback of open form, force to reparse the IFR binary\r
2495 //\r
2496 if (mHiiPackageListUpdated) {\r
2497 Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
2498 mHiiPackageListUpdated = FALSE;\r
2499 break;\r
2500 }\r
2501 }\r
eccfeab1
LG
2502 }\r
2503\r
7936fb6a 2504 //\r
2505 // Display form\r
2506 //\r
7c6c064c 2507 Status = DisplayForm ();\r
7936fb6a 2508 if (EFI_ERROR (Status)) {\r
13ad1def 2509 goto Done;\r
7936fb6a 2510 }\r
2511\r
2512 //\r
2513 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)\r
2514 //\r
2515 Statement = Selection->Statement;\r
2516 if (Statement != NULL) {\r
d1102dba
LG
2517 if ((ConfigAccess != NULL) &&\r
2518 ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&\r
13ad1def 2519 (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
798e4d22 2520 Status = ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
7c6c064c 2521 if (Statement->Operand == EFI_IFR_REF_OP) {\r
8ca6180f
ED
2522 //\r
2523 // Process dynamic update ref opcode.\r
2524 //\r
2525 if (!EFI_ERROR (Status)) {\r
7c6c064c 2526 Status = ProcessGotoOpCode(Statement, Selection);\r
8ca6180f 2527 }\r
d1102dba 2528\r
3dde743f 2529 //\r
8ca6180f 2530 // Callback return error status or status return from process goto opcode.\r
3dde743f 2531 //\r
8ca6180f 2532 if (EFI_ERROR (Status)) {\r
3dde743f 2533 //\r
00d1c2a3 2534 // Cross reference will not be taken, restore all essential field\r
3dde743f 2535 //\r
00d1c2a3
CS
2536 Selection->Handle = mCurrentHiiHandle;\r
2537 CopyMem (&Selection->FormSetGuid, &mCurrentFormSetGuid, sizeof (EFI_GUID));\r
2538 Selection->FormId = mCurrentFormId;\r
3dde743f 2539 Selection->QuestionId = 0;\r
00d1c2a3 2540 Selection->Action = UI_ACTION_REFRESH_FORM;\r
3dde743f 2541 }\r
7936fb6a 2542 }\r
b7891584 2543\r
a6c0ad81 2544\r
d1102dba
LG
2545 if (!EFI_ERROR (Status) &&\r
2546 (Statement->Operand != EFI_IFR_REF_OP) &&\r
ca2be854
ED
2547 ((Statement->Storage == NULL) || (Statement->Storage != NULL && Statement->ValueChanged))) {\r
2548 //\r
2549 // Only question value has been changed, browser will trig CHANGED callback.\r
2550 //\r
798e4d22 2551 ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
e6557276
DB
2552 //\r
2553 //check whether the question value changed compared with buffer value\r
2554 //if doesn't change ,set the ValueChanged flag to FALSE ,in order not to display the "configuration changed "information on the screen\r
2555 //\r
2556 IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
b7891584 2557 }\r
bfae1330 2558 } else {\r
a6c0ad81 2559 //\r
bfae1330 2560 // Do the question validation.\r
a6c0ad81 2561 //\r
bfae1330
ED
2562 Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
2563 if (!EFI_ERROR (Status) && (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
2564 SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
2565 //\r
2566 // Verify whether question value has checked, update the ValueChanged flag in Question.\r
2567 //\r
2568 IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
2569 }\r
7936fb6a 2570 }\r
892eccc8 2571\r
b1239a24 2572 //\r
d1102dba 2573 // If question has EFI_IFR_FLAG_RESET_REQUIRED/EFI_IFR_FLAG_RECONNECT_REQUIRED flag and without storage\r
f2e7732e 2574 // and process question success till here, trig the gResetFlag/gFlagReconnect.\r
b1239a24 2575 //\r
d1102dba
LG
2576 if ((Status == EFI_SUCCESS) &&\r
2577 (Statement->Storage == NULL)) {\r
f2e7732e 2578 if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0) {\r
b2dcae4c
BD
2579 gResetRequiredFormLevel = TRUE;\r
2580 gResetRequiredSystemLevel = TRUE;\r
f2e7732e
ED
2581 }\r
2582\r
2583 if ((Statement->QuestionFlags & EFI_IFR_FLAG_RECONNECT_REQUIRED) != 0) {\r
2584 gFlagReconnect = TRUE;\r
2585 }\r
b1239a24 2586 }\r
7936fb6a 2587 }\r
7936fb6a 2588\r
7c6c064c
ED
2589 //\r
2590 // Check whether Exit flag is TRUE.\r
2591 //\r
2592 if (gExitRequired) {\r
2593 switch (gBrowserSettingScope) {\r
2594 case SystemLevel:\r
2595 Selection->Action = UI_ACTION_EXIT;\r
2596 break;\r
2597\r
2598 case FormSetLevel:\r
2599 case FormLevel:\r
2600 FindNextMenu (Selection, gBrowserSettingScope);\r
2601 break;\r
2602\r
2603 default:\r
2604 break;\r
2605 }\r
2606\r
2607 gExitRequired = FALSE;\r
2608 }\r
2609\r
5adb8db7
LG
2610 //\r
2611 // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
2612 // for each question with callback flag.\r
2613 //\r
d1102dba
LG
2614 if ((ConfigAccess != NULL) &&\r
2615 ((Selection->Action == UI_ACTION_EXIT) ||\r
13ad1def
LG
2616 (Selection->Handle != mCurrentHiiHandle) ||\r
2617 (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
2618 (Selection->FormId != mCurrentFormId))) {\r
f4a2af1f 2619\r
798e4d22 2620 Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
b18e7050
ED
2621 if (EFI_ERROR (Status)) {\r
2622 goto Done;\r
f4a2af1f 2623 }\r
2624 }\r
5adb8db7 2625 } while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
f4a2af1f 2626\r
d66e6c16 2627Done:\r
13ad1def
LG
2628 //\r
2629 // Reset current form information to the initial setting when error happens or form exit.\r
2630 //\r
2631 if (EFI_ERROR (Status) || Selection->Action == UI_ACTION_EXIT) {\r
2632 mCurrentHiiHandle = NULL;\r
2633 CopyGuid (&mCurrentFormSetGuid, &gZeroGuid);\r
2634 mCurrentFormId = 0;\r
2635 }\r
2636\r
7936fb6a 2637 //\r
2638 // Unregister notify for Form package update\r
2639 //\r
13ad1def
LG
2640 mHiiDatabase->UnregisterPackageNotify (\r
2641 mHiiDatabase,\r
2642 NotifyHandle\r
2643 );\r
7936fb6a 2644 return Status;\r
2645}\r