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