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