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