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