]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Setup.c
CommitLineData
7936fb6a 1/** @file\r
2Entry and initialization module for the browser.\r
3\r
d1102dba 4Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
343f37b5 5(C) Copyright 2020 - 2022 Hewlett Packard Enterprise Development LP<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7936fb6a 7\r
8**/\r
9\r
10#include "Setup.h"\r
7936fb6a 11\r
12SETUP_DRIVER_PRIVATE_DATA mPrivateData = {\r
13 SETUP_DRIVER_SIGNATURE,\r
14 NULL,\r
15 {\r
16 SendForm,\r
17 BrowserCallback\r
48a9d5f7
LG
18 },\r
19 {\r
20 SetScope,\r
21 RegisterHotKey,\r
22 RegiserExitHandler,\r
23 SaveReminder\r
7c6c064c
ED
24 },\r
25 {\r
7da62bc0 26 BROWSER_EXTENSION2_VERSION_1_1,\r
7c6c064c
ED
27 SetScope,\r
28 RegisterHotKey,\r
29 RegiserExitHandler,\r
30 IsBrowserDataModified,\r
31 ExecuteAction,\r
1436aea4
MK
32 { NULL, NULL },\r
33 { NULL, NULL },\r
7da62bc0 34 IsResetRequired\r
7936fb6a 35 }\r
36};\r
37\r
1436aea4
MK
38EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
39EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;\r
40EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;\r
41EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;\r
42\r
43UINTN gBrowserContextCount = 0;\r
44LIST_ENTRY gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);\r
45LIST_ENTRY gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList);\r
46LIST_ENTRY gBrowserHotKeyList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);\r
47LIST_ENTRY gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);\r
48LIST_ENTRY gBrowserSaveFailFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserSaveFailFormSetList);\r
49\r
50BOOLEAN mSystemSubmit = FALSE;\r
51BOOLEAN gResetRequiredFormLevel;\r
52BOOLEAN gResetRequiredSystemLevel = FALSE;\r
53BOOLEAN gExitRequired;\r
54BOOLEAN gFlagReconnect;\r
55BOOLEAN gCallbackReconnect;\r
56BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;\r
57BOOLEAN mBrowserScopeFirstSet = TRUE;\r
58EXIT_HANDLER ExitHandlerFunction = NULL;\r
59FORM_BROWSER_FORMSET *mSystemLevelFormSet;\r
7936fb6a 60\r
61//\r
62// Browser Global Strings\r
63//\r
1436aea4
MK
64CHAR16 *gEmptyString;\r
65CHAR16 *mUnknownString = L"!";\r
b9feb4bd 66\r
1436aea4
MK
67extern EFI_GUID mCurrentFormSetGuid;\r
68extern EFI_HII_HANDLE mCurrentHiiHandle;\r
69extern UINT16 mCurrentFormId;\r
70extern FORM_DISPLAY_ENGINE_FORM gDisplayFormData;\r
7c6c064c
ED
71\r
72/**\r
73 Create a menu with specified formset GUID and form ID, and add it as a child\r
74 of the given parent menu.\r
75\r
76 @param HiiHandle Hii handle related to this formset.\r
77 @param FormSetGuid The Formset Guid of menu to be added.\r
78 @param FormId The Form ID of menu to be added.\r
79 @param QuestionId The question id of this menu to be added.\r
80\r
81 @return A pointer to the newly added menu or NULL if memory is insufficient.\r
82\r
83**/\r
84FORM_ENTRY_INFO *\r
85UiAddMenuList (\r
1436aea4
MK
86 IN EFI_HII_HANDLE HiiHandle,\r
87 IN EFI_GUID *FormSetGuid,\r
88 IN UINT16 FormId,\r
89 IN UINT16 QuestionId\r
7c6c064c
ED
90 )\r
91{\r
92 FORM_ENTRY_INFO *MenuList;\r
93\r
94 MenuList = AllocateZeroPool (sizeof (FORM_ENTRY_INFO));\r
95 if (MenuList == NULL) {\r
96 return NULL;\r
97 }\r
98\r
99 MenuList->Signature = FORM_ENTRY_INFO_SIGNATURE;\r
100\r
1436aea4 101 MenuList->HiiHandle = HiiHandle;\r
7c6c064c
ED
102 CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));\r
103 MenuList->FormId = FormId;\r
104 MenuList->QuestionId = QuestionId;\r
d66e6c16 105\r
7936fb6a 106 //\r
7c6c064c 107 // If parent is not specified, it is the root Form of a Formset\r
7936fb6a 108 //\r
7c6c064c
ED
109 InsertTailList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);\r
110\r
111 return MenuList;\r
112}\r
113\r
114/**\r
115 Return the form id for the input hiihandle and formset.\r
116\r
117 @param HiiHandle HiiHandle for FormSet.\r
118 @param FormSetGuid The Formset GUID of the menu to search.\r
119\r
120 @return First form's id for this form set.\r
121\r
122**/\r
123EFI_FORM_ID\r
124GetFirstFormId (\r
1436aea4
MK
125 IN EFI_HII_HANDLE HiiHandle,\r
126 IN EFI_GUID *FormSetGuid\r
7c6c064c
ED
127 )\r
128{\r
129 LIST_ENTRY *Link;\r
130 FORM_BROWSER_FORM *Form;\r
131\r
132 Link = GetFirstNode (&gCurrentSelection->FormSet->FormListHead);\r
133 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
134\r
135 return Form->FormId;\r
136}\r
137\r
138/**\r
139 Search Menu with given FormSetGuid and FormId in all cached menu list.\r
140\r
141 @param HiiHandle HiiHandle for FormSet.\r
142 @param FormSetGuid The Formset GUID of the menu to search.\r
143 @param FormId The Form ID of menu to search.\r
144\r
145 @return A pointer to menu found or NULL if not found.\r
146\r
147**/\r
148FORM_ENTRY_INFO *\r
149UiFindMenuList (\r
1436aea4
MK
150 IN EFI_HII_HANDLE HiiHandle,\r
151 IN EFI_GUID *FormSetGuid,\r
152 IN UINT16 FormId\r
7c6c064c
ED
153 )\r
154{\r
1436aea4
MK
155 LIST_ENTRY *Link;\r
156 FORM_ENTRY_INFO *MenuList;\r
157 FORM_ENTRY_INFO *RetMenu;\r
158 EFI_FORM_ID FirstFormId;\r
7c6c064c
ED
159\r
160 RetMenu = NULL;\r
161\r
162 Link = GetFirstNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
163 while (!IsNull (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link)) {\r
164 MenuList = FORM_ENTRY_INFO_FROM_LINK (Link);\r
1436aea4 165 Link = GetNextNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link);\r
d1102dba 166\r
7c6c064c
ED
167 //\r
168 // If already find the menu, free the menus behind it.\r
169 //\r
170 if (RetMenu != NULL) {\r
171 RemoveEntryList (&MenuList->Link);\r
172 FreePool (MenuList);\r
173 continue;\r
174 }\r
175\r
176 //\r
177 // Find the same FromSet.\r
178 //\r
179 if (MenuList->HiiHandle == HiiHandle) {\r
39cde03c 180 if (IsZeroGuid (&MenuList->FormSetGuid)) {\r
7c6c064c
ED
181 //\r
182 // FormSetGuid is not specified.\r
183 //\r
184 RetMenu = MenuList;\r
185 } else if (CompareGuid (&MenuList->FormSetGuid, FormSetGuid)) {\r
186 if (MenuList->FormId == FormId) {\r
187 RetMenu = MenuList;\r
1436aea4 188 } else if ((FormId == 0) || (MenuList->FormId == 0)) {\r
7c6c064c 189 FirstFormId = GetFirstFormId (HiiHandle, FormSetGuid);\r
1436aea4 190 if (((FormId == 0) && (FirstFormId == MenuList->FormId)) || ((MenuList->FormId == 0) && (FirstFormId == FormId))) {\r
7c6c064c
ED
191 RetMenu = MenuList;\r
192 }\r
193 }\r
7936fb6a 194 }\r
7c6c064c
ED
195 }\r
196 }\r
197\r
198 return RetMenu;\r
199}\r
200\r
201/**\r
202 Find parent menu for current menu.\r
203\r
204 @param CurrentMenu Current Menu\r
93551a01 205 @param SettingLevel Whether find parent menu in Form Level or Formset level.\r
d1102dba 206 In form level, just find the parent menu;\r
93551a01
ED
207 In formset level, find the parent menu which has different\r
208 formset guid value.\r
7c6c064c
ED
209\r
210 @retval The parent menu for current menu.\r
211**/\r
212FORM_ENTRY_INFO *\r
213UiFindParentMenu (\r
1436aea4
MK
214 IN FORM_ENTRY_INFO *CurrentMenu,\r
215 IN BROWSER_SETTING_SCOPE SettingLevel\r
7c6c064c
ED
216 )\r
217{\r
1436aea4
MK
218 FORM_ENTRY_INFO *ParentMenu;\r
219 LIST_ENTRY *Link;\r
93551a01
ED
220\r
221 ASSERT (SettingLevel == FormLevel || SettingLevel == FormSetLevel);\r
7c6c064c 222\r
93551a01
ED
223 if (CurrentMenu == NULL) {\r
224 return NULL;\r
225 }\r
d1102dba 226\r
7c6c064c 227 ParentMenu = NULL;\r
93551a01
ED
228 Link = &CurrentMenu->Link;\r
229\r
230 while (Link->BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
231 ParentMenu = FORM_ENTRY_INFO_FROM_LINK (Link->BackLink);\r
232\r
233 if (SettingLevel == FormLevel) {\r
234 //\r
235 // For FormLevel, just find the parent menu, return.\r
236 //\r
237 break;\r
238 }\r
239\r
240 if (!CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
241 //\r
242 // For SystemLevel, must find the menu which has different formset.\r
243 //\r
244 break;\r
245 }\r
246\r
247 Link = Link->BackLink;\r
248 }\r
249\r
250 //\r
251 // Not find the parent menu, just return NULL.\r
252 //\r
253 if (Link->BackLink == &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
254 return NULL;\r
7c6c064c
ED
255 }\r
256\r
257 return ParentMenu;\r
258}\r
259\r
260/**\r
261 Free Menu list linked list.\r
262\r
263 @param MenuListHead One Menu list point in the menu list.\r
264\r
265**/\r
266VOID\r
267UiFreeMenuList (\r
1436aea4 268 LIST_ENTRY *MenuListHead\r
7c6c064c
ED
269 )\r
270{\r
1436aea4 271 FORM_ENTRY_INFO *MenuList;\r
7c6c064c
ED
272\r
273 while (!IsListEmpty (MenuListHead)) {\r
274 MenuList = FORM_ENTRY_INFO_FROM_LINK (MenuListHead->ForwardLink);\r
275 RemoveEntryList (&MenuList->Link);\r
276\r
277 FreePool (MenuList);\r
278 }\r
279}\r
280\r
4d4deaac
ED
281/**\r
282 Copy current Menu list to the new menu list.\r
d1102dba 283\r
4d4deaac
ED
284 @param NewMenuListHead New create Menu list.\r
285 @param CurrentMenuListHead Current Menu list.\r
286\r
287**/\r
288VOID\r
289UiCopyMenuList (\r
1436aea4
MK
290 OUT LIST_ENTRY *NewMenuListHead,\r
291 IN LIST_ENTRY *CurrentMenuListHead\r
4d4deaac
ED
292 )\r
293{\r
1436aea4
MK
294 LIST_ENTRY *Link;\r
295 FORM_ENTRY_INFO *MenuList;\r
296 FORM_ENTRY_INFO *NewMenuEntry;\r
4d4deaac
ED
297\r
298 //\r
299 // If new menu list not empty, free it first.\r
300 //\r
301 UiFreeMenuList (NewMenuListHead);\r
302\r
303 Link = GetFirstNode (CurrentMenuListHead);\r
304 while (!IsNull (CurrentMenuListHead, Link)) {\r
305 MenuList = FORM_ENTRY_INFO_FROM_LINK (Link);\r
1436aea4 306 Link = GetNextNode (CurrentMenuListHead, Link);\r
4d4deaac
ED
307\r
308 NewMenuEntry = AllocateZeroPool (sizeof (FORM_ENTRY_INFO));\r
309 ASSERT (NewMenuEntry != NULL);\r
1436aea4
MK
310 NewMenuEntry->Signature = FORM_ENTRY_INFO_SIGNATURE;\r
311 NewMenuEntry->HiiHandle = MenuList->HiiHandle;\r
4d4deaac
ED
312 CopyMem (&NewMenuEntry->FormSetGuid, &MenuList->FormSetGuid, sizeof (EFI_GUID));\r
313 NewMenuEntry->FormId = MenuList->FormId;\r
314 NewMenuEntry->QuestionId = MenuList->QuestionId;\r
315\r
316 InsertTailList (NewMenuListHead, &NewMenuEntry->Link);\r
317 }\r
318}\r
319\r
7c6c064c
ED
320/**\r
321 Load all hii formset to the browser.\r
322\r
323**/\r
324VOID\r
325LoadAllHiiFormset (\r
326 VOID\r
327 )\r
328{\r
1436aea4
MK
329 FORM_BROWSER_FORMSET *LocalFormSet;\r
330 EFI_HII_HANDLE *HiiHandles;\r
331 UINTN Index;\r
332 EFI_GUID ZeroGuid;\r
333 EFI_STATUS Status;\r
334 FORM_BROWSER_FORMSET *OldFormset;\r
6e74560f
ED
335\r
336 OldFormset = mSystemLevelFormSet;\r
7c6c064c 337\r
7936fb6a 338 //\r
7c6c064c 339 // Get all the Hii handles\r
7936fb6a 340 //\r
7c6c064c
ED
341 HiiHandles = HiiGetHiiHandles (NULL);\r
342 ASSERT (HiiHandles != NULL);\r
343\r
7936fb6a 344 //\r
7c6c064c 345 // Search for formset of each class type\r
7936fb6a 346 //\r
7c6c064c
ED
347 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
348 //\r
349 // Check HiiHandles[Index] does exist in global maintain list.\r
350 //\r
351 if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {\r
352 continue;\r
353 }\r
354\r
355 //\r
356 // Initilize FormSet Setting\r
357 //\r
358 LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
359 ASSERT (LocalFormSet != NULL);\r
6e74560f
ED
360 mSystemLevelFormSet = LocalFormSet;\r
361\r
7c6c064c
ED
362 ZeroMem (&ZeroGuid, sizeof (ZeroGuid));\r
363 Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);\r
364 if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {\r
365 DestroyFormSet (LocalFormSet);\r
366 continue;\r
367 }\r
1436aea4 368\r
7c6c064c
ED
369 InitializeCurrentSetting (LocalFormSet);\r
370\r
371 //\r
372 // Initilize Questions' Value\r
373 //\r
374 Status = LoadFormSetConfig (NULL, LocalFormSet);\r
375 if (EFI_ERROR (Status)) {\r
376 DestroyFormSet (LocalFormSet);\r
377 continue;\r
378 }\r
379 }\r
380\r
7936fb6a 381 //\r
7c6c064c 382 // Free resources, and restore gOldFormSet and gClassOfVfr\r
7936fb6a 383 //\r
7c6c064c 384 FreePool (HiiHandles);\r
6e74560f
ED
385\r
386 mSystemLevelFormSet = OldFormset;\r
7c6c064c 387}\r
7936fb6a 388\r
bfae1330
ED
389/**\r
390 Pop up the error info.\r
391\r
392 @param BrowserStatus The input browser status.\r
4d4deaac 393 @param HiiHandle The Hiihandle for this opcode.\r
bfae1330
ED
394 @param OpCode The opcode use to get the erro info and timeout value.\r
395 @param ErrorString Error string used by BROWSER_NO_SUBMIT_IF.\r
396\r
397**/\r
4d4deaac 398UINT32\r
bfae1330 399PopupErrorMessage (\r
1436aea4
MK
400 IN UINT32 BrowserStatus,\r
401 IN EFI_HII_HANDLE HiiHandle,\r
402 IN EFI_IFR_OP_HEADER *OpCode OPTIONAL,\r
403 IN CHAR16 *ErrorString\r
bfae1330
ED
404 )\r
405{\r
1436aea4
MK
406 FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
407 USER_INPUT UserInputData;\r
bfae1330
ED
408\r
409 Statement = NULL;\r
410\r
411 if (OpCode != NULL) {\r
1436aea4 412 Statement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
bfae1330 413 ASSERT (Statement != NULL);\r
1436aea4 414 Statement->OpCode = OpCode;\r
bfae1330
ED
415 gDisplayFormData.HighLightedStatement = Statement;\r
416 }\r
417\r
418 //\r
419 // Used to compatible with old display engine.\r
420 // New display engine not use this field.\r
421 //\r
422 gDisplayFormData.ErrorString = ErrorString;\r
423 gDisplayFormData.BrowserStatus = BrowserStatus;\r
4d4deaac
ED
424\r
425 if (HiiHandle != NULL) {\r
1436aea4 426 gDisplayFormData.HiiHandle = HiiHandle;\r
4d4deaac
ED
427 }\r
428\r
429 mFormDisplay->FormDisplay (&gDisplayFormData, &UserInputData);\r
bfae1330
ED
430\r
431 gDisplayFormData.BrowserStatus = BROWSER_SUCCESS;\r
432 gDisplayFormData.ErrorString = NULL;\r
433\r
434 if (OpCode != NULL) {\r
435 FreePool (Statement);\r
436 }\r
4d4deaac
ED
437\r
438 return UserInputData.Action;\r
bfae1330
ED
439}\r
440\r
7936fb6a 441/**\r
442 This is the routine which an external caller uses to direct the browser\r
443 where to obtain it's information.\r
444\r
445\r
446 @param This The Form Browser protocol instanse.\r
447 @param Handles A pointer to an array of Handles. If HandleCount > 1 we\r
448 display a list of the formsets for the handles specified.\r
449 @param HandleCount The number of Handles specified in Handle.\r
450 @param FormSetGuid This field points to the EFI_GUID which must match the Guid\r
451 field in the EFI_IFR_FORM_SET op-code for the specified\r
452 forms-based package. If FormSetGuid is NULL, then this\r
453 function will display the first found forms package.\r
454 @param FormId This field specifies which EFI_IFR_FORM to render as the first\r
455 displayable page. If this field has a value of 0x0000, then\r
456 the forms browser will render the specified forms in their encoded order.\r
d66e6c16 457 @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in\r
7936fb6a 458 characters.\r
f02d0c0f 459 @param ActionRequest Points to the action recommended by the form.\r
7936fb6a 460\r
461 @retval EFI_SUCCESS The function completed successfully.\r
462 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
463 @retval EFI_NOT_FOUND No valid forms could be found to display.\r
464\r
465**/\r
466EFI_STATUS\r
467EFIAPI\r
468SendForm (\r
1436aea4
MK
469 IN CONST EFI_FORM_BROWSER2_PROTOCOL *This,\r
470 IN EFI_HII_HANDLE *Handles,\r
471 IN UINTN HandleCount,\r
472 IN EFI_GUID *FormSetGuid OPTIONAL,\r
473 IN UINT16 FormId OPTIONAL,\r
474 IN CONST EFI_SCREEN_DESCRIPTOR *ScreenDimensions OPTIONAL,\r
475 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest OPTIONAL\r
7936fb6a 476 )\r
477{\r
1436aea4
MK
478 EFI_STATUS Status;\r
479 UI_MENU_SELECTION *Selection;\r
480 UINTN Index;\r
481 FORM_BROWSER_FORMSET *FormSet;\r
482 FORM_ENTRY_INFO *MenuList;\r
483 BOOLEAN RetVal;\r
48a9d5f7
LG
484\r
485 //\r
7c6c064c 486 // If EDKII_FORM_DISPLAY_ENGINE_PROTOCOL not found, return EFI_UNSUPPORTED.\r
48a9d5f7 487 //\r
7c6c064c 488 if (mFormDisplay == NULL) {\r
0b5c288c 489 DEBUG ((DEBUG_ERROR, "Fatal Error! EDKII_FORM_DISPLAY_ENGINE_PROTOCOL not found!"));\r
7c6c064c 490 return EFI_UNSUPPORTED;\r
48a9d5f7 491 }\r
c40bd442 492\r
ce6d12cc 493 //\r
494 // Save globals used by SendForm()\r
495 //\r
496 SaveBrowserContext ();\r
497\r
1436aea4
MK
498 gFlagReconnect = FALSE;\r
499 gResetRequiredFormLevel = FALSE;\r
500 gExitRequired = FALSE;\r
501 gCallbackReconnect = FALSE;\r
502 Status = EFI_SUCCESS;\r
503 gEmptyString = L"";\r
504 gDisplayFormData.ScreenDimensions = (EFI_SCREEN_DESCRIPTOR *)ScreenDimensions;\r
519f076a 505\r
7936fb6a 506 for (Index = 0; Index < HandleCount; Index++) {\r
507 Selection = AllocateZeroPool (sizeof (UI_MENU_SELECTION));\r
508 ASSERT (Selection != NULL);\r
509\r
510 Selection->Handle = Handles[Index];\r
511 if (FormSetGuid != NULL) {\r
512 CopyMem (&Selection->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));\r
513 Selection->FormId = FormId;\r
48a9d5f7
LG
514 } else {\r
515 CopyMem (&Selection->FormSetGuid, &gEfiHiiPlatformSetupFormsetGuid, sizeof (EFI_GUID));\r
7936fb6a 516 }\r
517\r
518 do {\r
519 FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
520 ASSERT (FormSet != NULL);\r
521\r
93551a01
ED
522 //\r
523 // Validate the HiiHandle\r
524 // if validate failed, find the first validate parent HiiHandle.\r
525 //\r
1436aea4 526 if (!ValidateHiiHandle (Selection->Handle)) {\r
93551a01
ED
527 FindNextMenu (Selection, FormSetLevel);\r
528 }\r
529\r
7936fb6a 530 //\r
531 // Initialize internal data structures of FormSet\r
532 //\r
7c6c064c 533 Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet);\r
e8e36190 534 if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) {\r
7936fb6a 535 DestroyFormSet (FormSet);\r
536 break;\r
537 }\r
1436aea4
MK
538\r
539 Selection->FormSet = FormSet;\r
6e74560f 540 mSystemLevelFormSet = FormSet;\r
7936fb6a 541\r
7936fb6a 542 //\r
543 // Display this formset\r
544 //\r
545 gCurrentSelection = Selection;\r
546\r
547 Status = SetupBrowser (Selection);\r
548\r
1436aea4 549 gCurrentSelection = NULL;\r
6e74560f 550 mSystemLevelFormSet = NULL;\r
7936fb6a 551\r
365fdb0f 552 //\r
343f37b5 553 // Check incoming formset whether is same with previous. If yes, that means action is not exiting of formset so do not reconnect controller.\r
365fdb0f 554 //\r
343f37b5 555 if ((gFlagReconnect || gCallbackReconnect) && !CompareGuid (&FormSet->Guid, &Selection->FormSetGuid)) {\r
f2e7732e
ED
556 RetVal = ReconnectController (FormSet->DriverHandle);\r
557 if (!RetVal) {\r
1436aea4 558 PopupErrorMessage (BROWSER_RECONNECT_FAIL, NULL, NULL, NULL);\r
f2e7732e 559 }\r
1436aea4
MK
560\r
561 gFlagReconnect = FALSE;\r
f2e7732e
ED
562 gCallbackReconnect = FALSE;\r
563 }\r
564\r
25361615
ED
565 //\r
566 // If no data is changed, don't need to save current FormSet into the maintain list.\r
567 //\r
27c304f4 568 if (!IsNvUpdateRequiredForFormSet (FormSet)) {\r
1436aea4 569 CleanBrowserStorage (FormSet);\r
7c6c064c
ED
570 RemoveEntryList (&FormSet->Link);\r
571 DestroyFormSet (FormSet);\r
25361615 572 }\r
7c6c064c
ED
573\r
574 if (EFI_ERROR (Status)) {\r
575 break;\r
576 }\r
577 } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);\r
b9feb4bd 578\r
25361615 579 FreePool (Selection);\r
b9feb4bd
ED
580 }\r
581\r
7936fb6a 582 if (ActionRequest != NULL) {\r
583 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
b2dcae4c 584 if (gResetRequiredFormLevel) {\r
7936fb6a 585 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
586 }\r
587 }\r
588\r
1436aea4 589 mFormDisplay->ExitDisplay ();\r
7936fb6a 590\r
7c6c064c
ED
591 //\r
592 // Clear the menu history data.\r
593 //\r
594 while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {\r
595 MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);\r
596 RemoveEntryList (&MenuList->Link);\r
597 FreePool (MenuList);\r
598 }\r
7936fb6a 599\r
ce6d12cc 600 //\r
601 // Restore globals used by SendForm()\r
602 //\r
603 RestoreBrowserContext ();\r
604\r
7936fb6a 605 return Status;\r
606}\r
607\r
7c6c064c
ED
608/**\r
609 Get or set data to the storage.\r
610\r
611 @param ResultsDataSize The size of the buffer associatedwith ResultsData.\r
612 @param ResultsData A string returned from an IFR browser or\r
613 equivalent. The results string will have no\r
614 routing information in them.\r
615 @param RetrieveData A BOOLEAN field which allows an agent to retrieve\r
616 (if RetrieveData = TRUE) data from the uncommitted\r
617 browser state information or set (if RetrieveData\r
618 = FALSE) data in the uncommitted browser state\r
619 information.\r
620 @param Storage The pointer to the storage.\r
621\r
622 @retval EFI_SUCCESS The results have been distributed or are awaiting\r
623 distribution.\r
624\r
625**/\r
d1102dba 626EFI_STATUS\r
7c6c064c 627ProcessStorage (\r
1436aea4
MK
628 IN OUT UINTN *ResultsDataSize,\r
629 IN OUT EFI_STRING *ResultsData,\r
630 IN BOOLEAN RetrieveData,\r
631 IN BROWSER_STORAGE *Storage\r
7c6c064c
ED
632 )\r
633{\r
1436aea4
MK
634 CHAR16 *ConfigResp;\r
635 EFI_STATUS Status;\r
636 CHAR16 *StrPtr;\r
637 UINTN BufferSize;\r
638 UINTN TmpSize;\r
639 UINTN MaxLen;\r
640 FORMSET_STORAGE *BrowserStorage;\r
7c6c064c
ED
641\r
642 if (RetrieveData) {\r
643 //\r
644 // Generate <ConfigResp>\r
645 //\r
646 Status = StorageToConfigResp (Storage, &ConfigResp, Storage->ConfigRequest, TRUE);\r
647 if (EFI_ERROR (Status)) {\r
648 return Status;\r
649 }\r
650\r
651 //\r
652 // Skip <ConfigHdr> and '&' to point to <ConfigBody> when first copy the configbody.\r
653 // Also need to consider add "\0" at first time.\r
654 //\r
a35ecb75
ED
655 StrPtr = StrStr (ConfigResp, L"PATH");\r
656 ASSERT (StrPtr != NULL);\r
1436aea4
MK
657 StrPtr = StrStr (StrPtr, L"&");\r
658 StrPtr += 1;\r
7c6c064c
ED
659 BufferSize = StrSize (StrPtr);\r
660\r
7c6c064c
ED
661 //\r
662 // Copy the data if the input buffer is bigger enough.\r
663 //\r
664 if (*ResultsDataSize >= BufferSize) {\r
5ad66ec6 665 StrCpyS (*ResultsData, *ResultsDataSize / sizeof (CHAR16), StrPtr);\r
7c6c064c
ED
666 }\r
667\r
668 *ResultsDataSize = BufferSize;\r
669 FreePool (ConfigResp);\r
670 } else {\r
671 //\r
672 // Prepare <ConfigResp>\r
673 //\r
a35ecb75
ED
674 BrowserStorage = GetFstStgFromBrsStg (Storage);\r
675 ASSERT (BrowserStorage != NULL);\r
1436aea4 676 TmpSize = StrLen (*ResultsData);\r
a35ecb75 677 BufferSize = (TmpSize + StrLen (BrowserStorage->ConfigHdr) + 2) * sizeof (CHAR16);\r
1436aea4 678 MaxLen = BufferSize / sizeof (CHAR16);\r
7c6c064c
ED
679 ConfigResp = AllocateZeroPool (BufferSize);\r
680 ASSERT (ConfigResp != NULL);\r
681\r
5ad66ec6
DB
682 StrCpyS (ConfigResp, MaxLen, BrowserStorage->ConfigHdr);\r
683 StrCatS (ConfigResp, MaxLen, L"&");\r
684 StrCatS (ConfigResp, MaxLen, *ResultsData);\r
7c6c064c
ED
685\r
686 //\r
687 // Update Browser uncommited data\r
688 //\r
689 Status = ConfigRespToStorage (Storage, ConfigResp);\r
690 FreePool (ConfigResp);\r
691 if (EFI_ERROR (Status)) {\r
692 return Status;\r
693 }\r
694 }\r
695\r
696 return EFI_SUCCESS;\r
697}\r
7936fb6a 698\r
699/**\r
d1102dba
LG
700 This routine called this service in the browser to retrieve or set certain uncommitted\r
701 state information that resides in the open formsets.\r
7936fb6a 702\r
703 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL\r
704 instance.\r
705 @param ResultsDataSize A pointer to the size of the buffer associated\r
706 with ResultsData.\r
707 @param ResultsData A string returned from an IFR browser or\r
708 equivalent. The results string will have no\r
709 routing information in them.\r
710 @param RetrieveData A BOOLEAN field which allows an agent to retrieve\r
711 (if RetrieveData = TRUE) data from the uncommitted\r
712 browser state information or set (if RetrieveData\r
713 = FALSE) data in the uncommitted browser state\r
714 information.\r
715 @param VariableGuid An optional field to indicate the target variable\r
716 GUID name to use.\r
717 @param VariableName An optional field to indicate the target\r
718 human-readable variable name.\r
719\r
720 @retval EFI_SUCCESS The results have been distributed or are awaiting\r
721 distribution.\r
722 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to\r
723 contain the results data.\r
724\r
725**/\r
726EFI_STATUS\r
727EFIAPI\r
728BrowserCallback (\r
729 IN CONST EFI_FORM_BROWSER2_PROTOCOL *This,\r
730 IN OUT UINTN *ResultsDataSize,\r
731 IN OUT EFI_STRING ResultsData,\r
732 IN BOOLEAN RetrieveData,\r
e3917e22 733 IN CONST EFI_GUID *VariableGuid OPTIONAL,\r
7936fb6a 734 IN CONST CHAR16 *VariableName OPTIONAL\r
735 )\r
736{\r
1436aea4
MK
737 EFI_STATUS Status;\r
738 LIST_ENTRY *Link;\r
739 BROWSER_STORAGE *Storage;\r
740 FORMSET_STORAGE *FormsetStorage;\r
741 UINTN TotalSize;\r
742 BOOLEAN Found;\r
7936fb6a 743\r
1436aea4 744 if ((ResultsDataSize == NULL) || (ResultsData == NULL)) {\r
7936fb6a 745 return EFI_INVALID_PARAMETER;\r
746 }\r
747\r
7c6c064c
ED
748 TotalSize = *ResultsDataSize;\r
749 Storage = NULL;\r
750 Found = FALSE;\r
751 Status = EFI_SUCCESS;\r
7936fb6a 752\r
7936fb6a 753 if (VariableGuid != NULL) {\r
754 //\r
7c6c064c 755 // Try to find target storage in the current formset.\r
7936fb6a 756 //\r
7c6c064c
ED
757 Link = GetFirstNode (&gBrowserStorageList);\r
758 while (!IsNull (&gBrowserStorageList, Link)) {\r
759 Storage = BROWSER_STORAGE_FROM_LINK (Link);\r
1436aea4 760 Link = GetNextNode (&gBrowserStorageList, Link);\r
7c6c064c
ED
761 //\r
762 // Check the current storage.\r
763 //\r
1436aea4 764 if (!CompareGuid (&Storage->Guid, (EFI_GUID *)VariableGuid)) {\r
7c6c064c
ED
765 continue;\r
766 }\r
7936fb6a 767\r
1436aea4
MK
768 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ||\r
769 (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))\r
770 {\r
7c6c064c
ED
771 //\r
772 // Buffer storage require both GUID and Name\r
773 //\r
774 if (VariableName == NULL) {\r
775 return EFI_NOT_FOUND;\r
776 }\r
7936fb6a 777\r
1436aea4 778 if (StrCmp (Storage->Name, (CHAR16 *)VariableName) != 0) {\r
7c6c064c 779 continue;\r
7936fb6a 780 }\r
7936fb6a 781 }\r
7c6c064c 782\r
1436aea4
MK
783 if ((Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
784 (Storage->Type == EFI_HII_VARSTORE_BUFFER))\r
785 {\r
786 if ((mSystemLevelFormSet == NULL) || (mSystemLevelFormSet->HiiHandle == NULL)) {\r
fae73624
ED
787 return EFI_NOT_FOUND;\r
788 }\r
789\r
790 if (Storage->HiiHandle != mSystemLevelFormSet->HiiHandle) {\r
791 continue;\r
792 }\r
793 }\r
794\r
7c6c064c
ED
795 Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);\r
796 if (EFI_ERROR (Status)) {\r
797 return Status;\r
798 }\r
799\r
9d34cac8
ED
800 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
801 ConfigRequestAdjust (Storage, ResultsData, TRUE);\r
802 }\r
803\r
7c6c064c
ED
804 //\r
805 // Different formsets may have same varstore, so here just set the flag\r
806 // not exit the circle.\r
d1102dba 807 //\r
7c6c064c
ED
808 Found = TRUE;\r
809 break;\r
7936fb6a 810 }\r
811\r
812 if (!Found) {\r
813 return EFI_NOT_FOUND;\r
814 }\r
815 } else {\r
816 //\r
817 // GUID/Name is not specified, take the first storage in FormSet\r
818 //\r
6e74560f 819 if (mSystemLevelFormSet == NULL) {\r
7c6c064c 820 return EFI_NOT_READY;\r
b9feb4bd
ED
821 }\r
822\r
25361615
ED
823 //\r
824 // Generate <ConfigResp>\r
825 //\r
6e74560f
ED
826 Link = GetFirstNode (&mSystemLevelFormSet->StorageListHead);\r
827 if (IsNull (&mSystemLevelFormSet->StorageListHead, Link)) {\r
7c6c064c
ED
828 return EFI_UNSUPPORTED;\r
829 }\r
830\r
831 FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
d1102dba 832\r
7c6c064c 833 Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, FormsetStorage->BrowserStorage);\r
7936fb6a 834 if (EFI_ERROR (Status)) {\r
835 return Status;\r
836 }\r
7c6c064c 837 }\r
7936fb6a 838\r
7c6c064c 839 if (RetrieveData) {\r
1436aea4 840 Status = TotalSize <= *ResultsDataSize ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
7c6c064c
ED
841 *ResultsDataSize = TotalSize;\r
842 }\r
d1102dba 843\r
7c6c064c 844 return Status;\r
7c6c064c 845}\r
7936fb6a 846\r
7c6c064c
ED
847/**\r
848 Callback function for SimpleTextInEx protocol install events\r
7936fb6a 849\r
7c6c064c
ED
850 @param Event the event that is signaled.\r
851 @param Context not used here.\r
7936fb6a 852\r
7c6c064c
ED
853**/\r
854VOID\r
855EFIAPI\r
856FormDisplayCallback (\r
1436aea4
MK
857 IN EFI_EVENT Event,\r
858 IN VOID *Context\r
7c6c064c
ED
859 )\r
860{\r
7c6c064c
ED
861 if (mFormDisplay != NULL) {\r
862 return;\r
7936fb6a 863 }\r
864\r
831537d6 865 gBS->LocateProtocol (\r
1436aea4
MK
866 &gEdkiiFormDisplayEngineProtocolGuid,\r
867 NULL,\r
868 (VOID **)&mFormDisplay\r
869 );\r
7936fb6a 870}\r
871\r
7936fb6a 872/**\r
873 Initialize Setup Browser driver.\r
874\r
875 @param ImageHandle The image handle.\r
876 @param SystemTable The system table.\r
877\r
878 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..\r
879 @return Other value if failed to initialize the Setup Browser module.\r
880\r
881**/\r
882EFI_STATUS\r
883EFIAPI\r
884InitializeSetup (\r
1436aea4
MK
885 IN EFI_HANDLE ImageHandle,\r
886 IN EFI_SYSTEM_TABLE *SystemTable\r
7936fb6a 887 )\r
888{\r
1436aea4
MK
889 EFI_STATUS Status;\r
890 VOID *Registration;\r
7936fb6a 891\r
892 //\r
893 // Locate required Hii relative protocols\r
894 //\r
895 Status = gBS->LocateProtocol (\r
896 &gEfiHiiDatabaseProtocolGuid,\r
897 NULL,\r
1436aea4 898 (VOID **)&mHiiDatabase\r
7936fb6a 899 );\r
900 ASSERT_EFI_ERROR (Status);\r
901\r
7936fb6a 902 Status = gBS->LocateProtocol (\r
903 &gEfiHiiConfigRoutingProtocolGuid,\r
904 NULL,\r
1436aea4 905 (VOID **)&mHiiConfigRouting\r
7936fb6a 906 );\r
907 ASSERT_EFI_ERROR (Status);\r
908\r
80a047f0
ED
909 Status = gBS->LocateProtocol (\r
910 &gEfiDevicePathFromTextProtocolGuid,\r
911 NULL,\r
1436aea4 912 (VOID **)&mPathFromText\r
80a047f0
ED
913 );\r
914\r
7936fb6a 915 //\r
916 // Install FormBrowser2 protocol\r
917 //\r
918 mPrivateData.Handle = NULL;\r
1436aea4
MK
919 Status = gBS->InstallProtocolInterface (\r
920 &mPrivateData.Handle,\r
921 &gEfiFormBrowser2ProtocolGuid,\r
922 EFI_NATIVE_INTERFACE,\r
923 &mPrivateData.FormBrowser2\r
924 );\r
7936fb6a 925 ASSERT_EFI_ERROR (Status);\r
926\r
48a9d5f7 927 //\r
7c6c064c 928 // Install FormBrowserEx2 protocol\r
48a9d5f7 929 //\r
184f3a02
ED
930 InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
931 InitializeListHead (&mPrivateData.FormBrowserEx2.OverrideQestListHead);\r
48a9d5f7 932 mPrivateData.Handle = NULL;\r
1436aea4
MK
933 Status = gBS->InstallProtocolInterface (\r
934 &mPrivateData.Handle,\r
935 &gEdkiiFormBrowserEx2ProtocolGuid,\r
936 EFI_NATIVE_INTERFACE,\r
937 &mPrivateData.FormBrowserEx2\r
938 );\r
7c6c064c 939 ASSERT_EFI_ERROR (Status);\r
d1102dba 940\r
48a9d5f7
LG
941 Status = gBS->InstallProtocolInterface (\r
942 &mPrivateData.Handle,\r
2fa0e11d 943 &gEdkiiFormBrowserExProtocolGuid,\r
48a9d5f7
LG
944 EFI_NATIVE_INTERFACE,\r
945 &mPrivateData.FormBrowserEx\r
946 );\r
7c6c064c
ED
947 ASSERT_EFI_ERROR (Status);\r
948\r
949 InitializeDisplayFormData ();\r
950\r
951 Status = gBS->LocateProtocol (\r
952 &gEdkiiFormDisplayEngineProtocolGuid,\r
953 NULL,\r
1436aea4 954 (VOID **)&mFormDisplay\r
7c6c064c 955 );\r
48a9d5f7 956\r
7c6c064c
ED
957 if (EFI_ERROR (Status)) {\r
958 EfiCreateProtocolNotifyEvent (\r
959 &gEdkiiFormDisplayEngineProtocolGuid,\r
960 TPL_CALLBACK,\r
961 FormDisplayCallback,\r
962 NULL,\r
963 &Registration\r
964 );\r
965 }\r
d1102dba 966\r
7c6c064c 967 return EFI_SUCCESS;\r
7936fb6a 968}\r
969\r
7936fb6a 970/**\r
971 Create a new string in HII Package List.\r
972\r
973 @param String The String to be added\r
974 @param HiiHandle The package list in the HII database to insert the\r
975 specified string.\r
976\r
977 @return The output string.\r
978\r
979**/\r
980EFI_STRING_ID\r
981NewString (\r
1436aea4
MK
982 IN CHAR16 *String,\r
983 IN EFI_HII_HANDLE HiiHandle\r
7936fb6a 984 )\r
985{\r
986 EFI_STRING_ID StringId;\r
7936fb6a 987\r
cb7d01c0 988 StringId = HiiSetString (HiiHandle, 0, String, NULL);\r
989 ASSERT (StringId != 0);\r
7936fb6a 990\r
991 return StringId;\r
992}\r
993\r
7936fb6a 994/**\r
995 Delete a string from HII Package List.\r
996\r
997 @param StringId Id of the string in HII database.\r
998 @param HiiHandle The HII package list handle.\r
999\r
1000 @retval EFI_SUCCESS The string was deleted successfully.\r
1001\r
1002**/\r
1003EFI_STATUS\r
1004DeleteString (\r
1436aea4
MK
1005 IN EFI_STRING_ID StringId,\r
1006 IN EFI_HII_HANDLE HiiHandle\r
7936fb6a 1007 )\r
1008{\r
1009 CHAR16 NullChar;\r
1010\r
1011 NullChar = CHAR_NULL;\r
cb7d01c0 1012 HiiSetString (HiiHandle, StringId, &NullChar, NULL);\r
1013 return EFI_SUCCESS;\r
7936fb6a 1014}\r
1015\r
7936fb6a 1016/**\r
1017 Get the string based on the StringId and HII Package List Handle.\r
1018\r
1019 @param Token The String's ID.\r
1020 @param HiiHandle The package list in the HII database to search for\r
1021 the specified string.\r
1022\r
1023 @return The output string.\r
1024\r
1025**/\r
1026CHAR16 *\r
1027GetToken (\r
1436aea4
MK
1028 IN EFI_STRING_ID Token,\r
1029 IN EFI_HII_HANDLE HiiHandle\r
7936fb6a 1030 )\r
1031{\r
cb7d01c0 1032 EFI_STRING String;\r
7936fb6a 1033\r
2573712e
LG
1034 if (HiiHandle == NULL) {\r
1035 return NULL;\r
1036 }\r
1037\r
cb7d01c0 1038 String = HiiGetString (HiiHandle, Token, NULL);\r
0e8e994d 1039 if (String == NULL) {\r
d6bee311 1040 String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);\r
0e8e994d 1041 ASSERT (String != NULL);\r
1042 }\r
7936fb6a 1043\r
1436aea4
MK
1044 return (CHAR16 *)String;\r
1045}\r
7936fb6a 1046\r
1047/**\r
1048 Allocate new memory and then copy the Unicode string Source to Destination.\r
1049\r
1050 @param Dest Location to copy string\r
1051 @param Src String to copy\r
1052\r
1053**/\r
1054VOID\r
1055NewStringCpy (\r
1436aea4
MK
1056 IN OUT CHAR16 **Dest,\r
1057 IN CHAR16 *Src\r
7936fb6a 1058 )\r
1059{\r
676df92c 1060 if (*Dest != NULL) {\r
1061 FreePool (*Dest);\r
1062 }\r
1436aea4 1063\r
7936fb6a 1064 *Dest = AllocateCopyPool (StrSize (Src), Src);\r
1065 ASSERT (*Dest != NULL);\r
1066}\r
1067\r
7936fb6a 1068/**\r
1069 Allocate new memory and concatinate Source on the end of Destination.\r
1070\r
1071 @param Dest String to added to the end of.\r
1072 @param Src String to concatinate.\r
1073\r
1074**/\r
1075VOID\r
1076NewStringCat (\r
1436aea4
MK
1077 IN OUT CHAR16 **Dest,\r
1078 IN CHAR16 *Src\r
7936fb6a 1079 )\r
1080{\r
1081 CHAR16 *NewString;\r
5ad66ec6 1082 UINTN MaxLen;\r
7936fb6a 1083\r
1084 if (*Dest == NULL) {\r
1085 NewStringCpy (Dest, Src);\r
1086 return;\r
1087 }\r
1088\r
1436aea4 1089 MaxLen = (StrSize (*Dest) + StrSize (Src) - 1) / sizeof (CHAR16);\r
5ad66ec6 1090 NewString = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
25361615
ED
1091 ASSERT (NewString != NULL);\r
1092\r
5ad66ec6
DB
1093 StrCpyS (NewString, MaxLen, *Dest);\r
1094 StrCatS (NewString, MaxLen, Src);\r
25361615
ED
1095\r
1096 FreePool (*Dest);\r
1097 *Dest = NewString;\r
1098}\r
1099\r
7936fb6a 1100/**\r
1101 Get Value for given Name from a NameValue Storage.\r
1102\r
1103 @param Storage The NameValue Storage.\r
1104 @param Name The Name.\r
1105 @param Value The retured Value.\r
816a7110 1106 @param GetValueFrom Where to get source value, from EditValue or Value.\r
7936fb6a 1107\r
1108 @retval EFI_SUCCESS Value found for given Name.\r
1109 @retval EFI_NOT_FOUND No such Name found in NameValue storage.\r
1110\r
1111**/\r
1112EFI_STATUS\r
1113GetValueByName (\r
1436aea4
MK
1114 IN BROWSER_STORAGE *Storage,\r
1115 IN CHAR16 *Name,\r
1116 IN OUT CHAR16 **Value,\r
1117 IN GET_SET_QUESTION_VALUE_WITH GetValueFrom\r
7936fb6a 1118 )\r
1119{\r
1436aea4
MK
1120 LIST_ENTRY *Link;\r
1121 NAME_VALUE_NODE *Node;\r
7936fb6a 1122\r
1436aea4 1123 if ((GetValueFrom != GetSetValueWithEditBuffer) && (GetValueFrom != GetSetValueWithBuffer)) {\r
816a7110
ED
1124 return EFI_INVALID_PARAMETER;\r
1125 }\r
1126\r
7936fb6a 1127 *Value = NULL;\r
1128\r
1129 Link = GetFirstNode (&Storage->NameValueListHead);\r
1130 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
1131 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
1132\r
1133 if (StrCmp (Name, Node->Name) == 0) {\r
816a7110
ED
1134 if (GetValueFrom == GetSetValueWithEditBuffer) {\r
1135 NewStringCpy (Value, Node->EditValue);\r
1136 } else {\r
1137 NewStringCpy (Value, Node->Value);\r
1138 }\r
1436aea4 1139\r
7936fb6a 1140 return EFI_SUCCESS;\r
1141 }\r
1142\r
1143 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
1144 }\r
1145\r
1146 return EFI_NOT_FOUND;\r
1147}\r
1148\r
7936fb6a 1149/**\r
1150 Set Value of given Name in a NameValue Storage.\r
1151\r
1152 @param Storage The NameValue Storage.\r
1153 @param Name The Name.\r
1154 @param Value The Value to set.\r
816a7110 1155 @param SetValueTo Whether update editValue or Value.\r
7c6c064c 1156 @param ReturnNode The node use the input name.\r
7936fb6a 1157\r
1158 @retval EFI_SUCCESS Value found for given Name.\r
1159 @retval EFI_NOT_FOUND No such Name found in NameValue storage.\r
1160\r
1161**/\r
1162EFI_STATUS\r
1163SetValueByName (\r
1436aea4
MK
1164 IN BROWSER_STORAGE *Storage,\r
1165 IN CHAR16 *Name,\r
1166 IN CHAR16 *Value,\r
1167 IN GET_SET_QUESTION_VALUE_WITH SetValueTo,\r
1168 OUT NAME_VALUE_NODE **ReturnNode\r
7936fb6a 1169 )\r
1170{\r
1436aea4
MK
1171 LIST_ENTRY *Link;\r
1172 NAME_VALUE_NODE *Node;\r
1173 CHAR16 *Buffer;\r
7936fb6a 1174\r
1436aea4 1175 if ((SetValueTo != GetSetValueWithEditBuffer) && (SetValueTo != GetSetValueWithBuffer)) {\r
816a7110
ED
1176 return EFI_INVALID_PARAMETER;\r
1177 }\r
1178\r
7936fb6a 1179 Link = GetFirstNode (&Storage->NameValueListHead);\r
1180 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
1181 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
1182\r
1183 if (StrCmp (Name, Node->Name) == 0) {\r
816a7110 1184 if (SetValueTo == GetSetValueWithEditBuffer) {\r
b18e7050
ED
1185 Buffer = Node->EditValue;\r
1186 } else {\r
1187 Buffer = Node->Value;\r
1188 }\r
1436aea4 1189\r
b18e7050
ED
1190 if (Buffer != NULL) {\r
1191 FreePool (Buffer);\r
1192 }\r
1436aea4 1193\r
b18e7050
ED
1194 Buffer = AllocateCopyPool (StrSize (Value), Value);\r
1195 ASSERT (Buffer != NULL);\r
816a7110 1196 if (SetValueTo == GetSetValueWithEditBuffer) {\r
b18e7050
ED
1197 Node->EditValue = Buffer;\r
1198 } else {\r
1199 Node->Value = Buffer;\r
676df92c 1200 }\r
7c6c064c
ED
1201\r
1202 if (ReturnNode != NULL) {\r
1203 *ReturnNode = Node;\r
1204 }\r
1205\r
7936fb6a 1206 return EFI_SUCCESS;\r
1207 }\r
1208\r
1209 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
1210 }\r
1211\r
1212 return EFI_NOT_FOUND;\r
1213}\r
1214\r
7936fb6a 1215/**\r
1216 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.\r
1217\r
94f3aae7 1218 @param Storage The Storage to be conveted.\r
7936fb6a 1219 @param ConfigResp The returned <ConfigResp>.\r
94f3aae7 1220 @param ConfigRequest The ConfigRequest string.\r
7c6c064c 1221 @param GetEditBuf Get the data from editbuffer or buffer.\r
7936fb6a 1222\r
1223 @retval EFI_SUCCESS Convert success.\r
1224 @retval EFI_INVALID_PARAMETER Incorrect storage type.\r
1225\r
1226**/\r
1227EFI_STATUS\r
1228StorageToConfigResp (\r
1436aea4
MK
1229 IN BROWSER_STORAGE *Storage,\r
1230 IN CHAR16 **ConfigResp,\r
1231 IN CHAR16 *ConfigRequest,\r
1232 IN BOOLEAN GetEditBuf\r
7936fb6a 1233 )\r
1234{\r
1436aea4
MK
1235 EFI_STATUS Status;\r
1236 EFI_STRING Progress;\r
1237 LIST_ENTRY *Link;\r
1238 NAME_VALUE_NODE *Node;\r
1239 UINT8 *SourceBuf;\r
1240 FORMSET_STORAGE *FormsetStorage;\r
7936fb6a 1241\r
1242 Status = EFI_SUCCESS;\r
1243\r
1244 switch (Storage->Type) {\r
1436aea4
MK
1245 case EFI_HII_VARSTORE_BUFFER:\r
1246 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
1247 SourceBuf = GetEditBuf ? Storage->EditBuffer : Storage->Buffer;\r
1248 Status = mHiiConfigRouting->BlockToConfig (\r
1249 mHiiConfigRouting,\r
1250 ConfigRequest,\r
1251 SourceBuf,\r
1252 Storage->Size,\r
1253 ConfigResp,\r
1254 &Progress\r
1255 );\r
1256 break;\r
7936fb6a 1257\r
1436aea4
MK
1258 case EFI_HII_VARSTORE_NAME_VALUE:\r
1259 *ConfigResp = NULL;\r
1260 FormsetStorage = GetFstStgFromBrsStg (Storage);\r
1261 ASSERT (FormsetStorage != NULL);\r
1262 NewStringCat (ConfigResp, FormsetStorage->ConfigHdr);\r
1263\r
1264 Link = GetFirstNode (&Storage->NameValueListHead);\r
1265 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
1266 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
1267\r
1268 if (StrStr (ConfigRequest, Node->Name) != NULL) {\r
1269 NewStringCat (ConfigResp, L"&");\r
1270 NewStringCat (ConfigResp, Node->Name);\r
1271 NewStringCat (ConfigResp, L"=");\r
1272 if (GetEditBuf) {\r
1273 NewStringCat (ConfigResp, Node->EditValue);\r
1274 } else {\r
1275 NewStringCat (ConfigResp, Node->Value);\r
1276 }\r
7c6c064c 1277 }\r
1436aea4
MK
1278\r
1279 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
b18e7050 1280 }\r
7936fb6a 1281\r
1436aea4
MK
1282 break;\r
1283\r
1284 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
1285 default:\r
1286 Status = EFI_INVALID_PARAMETER;\r
1287 break;\r
7936fb6a 1288 }\r
1289\r
1290 return Status;\r
1291}\r
1292\r
7936fb6a 1293/**\r
1294 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.\r
1295\r
1296 @param Storage The Storage to receive the settings.\r
1297 @param ConfigResp The <ConfigResp> to be converted.\r
1298\r
1299 @retval EFI_SUCCESS Convert success.\r
1300 @retval EFI_INVALID_PARAMETER Incorrect storage type.\r
1301\r
1302**/\r
1303EFI_STATUS\r
1304ConfigRespToStorage (\r
1436aea4
MK
1305 IN BROWSER_STORAGE *Storage,\r
1306 IN CHAR16 *ConfigResp\r
7936fb6a 1307 )\r
1308{\r
1309 EFI_STATUS Status;\r
1310 EFI_STRING Progress;\r
1311 UINTN BufferSize;\r
1312 CHAR16 *StrPtr;\r
1313 CHAR16 *Name;\r
1314 CHAR16 *Value;\r
1315\r
1316 Status = EFI_SUCCESS;\r
1317\r
1318 switch (Storage->Type) {\r
1436aea4
MK
1319 case EFI_HII_VARSTORE_BUFFER:\r
1320 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
1321 BufferSize = Storage->Size;\r
1322 Status = mHiiConfigRouting->ConfigToBlock (\r
1323 mHiiConfigRouting,\r
1324 ConfigResp,\r
1325 Storage->EditBuffer,\r
1326 &BufferSize,\r
1327 &Progress\r
1328 );\r
40245175 1329 break;\r
1436aea4
MK
1330\r
1331 case EFI_HII_VARSTORE_NAME_VALUE:\r
1332 StrPtr = StrStr (ConfigResp, L"PATH");\r
7936fb6a 1333 if (StrPtr == NULL) {\r
1334 break;\r
1335 }\r
7936fb6a 1336\r
1436aea4
MK
1337 StrPtr = StrStr (ConfigResp, L"&");\r
1338 while (StrPtr != NULL) {\r
1339 //\r
1340 // Skip '&'\r
1341 //\r
1342 StrPtr = StrPtr + 1;\r
1343 Name = StrPtr;\r
1344 StrPtr = StrStr (StrPtr, L"=");\r
1345 if (StrPtr == NULL) {\r
1346 break;\r
1347 }\r
1348\r
7936fb6a 1349 *StrPtr = 0;\r
1436aea4
MK
1350\r
1351 //\r
1352 // Skip '='\r
1353 //\r
1354 StrPtr = StrPtr + 1;\r
1355 Value = StrPtr;\r
1356 StrPtr = StrStr (StrPtr, L"&");\r
1357 if (StrPtr != NULL) {\r
1358 *StrPtr = 0;\r
1359 }\r
1360\r
1361 SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer, NULL);\r
7936fb6a 1362 }\r
7936fb6a 1363\r
1436aea4
MK
1364 break;\r
1365\r
1366 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
1367 default:\r
1368 Status = EFI_INVALID_PARAMETER;\r
1369 break;\r
7936fb6a 1370 }\r
1371\r
1372 return Status;\r
1373}\r
1374\r
560a435d
DB
1375/**\r
1376 Get bit field value from the buffer and then set the value for the question.\r
1377 Note: Data type UINT32 can cover all the bit field value.\r
1378\r
1379 @param Question The question refer to bit field.\r
1380 @param Buffer Point to the buffer which the question value get from.\r
1381\r
1382**/\r
1383VOID\r
1384GetBitsQuestionValue (\r
1436aea4
MK
1385 IN FORM_BROWSER_STATEMENT *Question,\r
1386 IN UINT8 *Buffer\r
560a435d
DB
1387 )\r
1388{\r
1436aea4
MK
1389 UINTN StartBit;\r
1390 UINTN EndBit;\r
1391 UINT32 RetVal;\r
1392 UINT32 BufferValue;\r
560a435d
DB
1393\r
1394 StartBit = Question->BitVarOffset % 8;\r
1436aea4 1395 EndBit = StartBit + Question->BitStorageWidth - 1;\r
560a435d 1396\r
1436aea4 1397 CopyMem ((UINT8 *)&BufferValue, Buffer, Question->StorageWidth);\r
560a435d
DB
1398\r
1399 RetVal = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
1400\r
1401 //\r
1402 // Set question value.\r
1403 // Note: Since Question with BufferValue (orderedlist, password, string)are not supported to refer bit field.\r
1404 // Only oneof/checkbox/oneof can support bit field.So we can copy the value to the Hiivalue of Question directly.\r
1405 //\r
1436aea4 1406 CopyMem ((UINT8 *)&Question->HiiValue.Value, (UINT8 *)&RetVal, Question->StorageWidth);\r
560a435d
DB
1407}\r
1408\r
1409/**\r
1410 Set bit field value to the buffer.\r
1411 Note: Data type UINT32 can cover all the bit field value.\r
1412\r
1413 @param Question The question refer to bit field.\r
1414 @param Buffer Point to the buffer which the question value set to.\r
1415 @param Value The bit field value need to set.\r
1416\r
1417**/\r
1418VOID\r
1419SetBitsQuestionValue (\r
1436aea4
MK
1420 IN FORM_BROWSER_STATEMENT *Question,\r
1421 IN OUT UINT8 *Buffer,\r
1422 IN UINT32 Value\r
560a435d
DB
1423 )\r
1424{\r
1436aea4
MK
1425 UINT32 Operand;\r
1426 UINTN StartBit;\r
1427 UINTN EndBit;\r
1428 UINT32 RetVal;\r
560a435d
DB
1429\r
1430 StartBit = Question->BitVarOffset % 8;\r
1436aea4 1431 EndBit = StartBit + Question->BitStorageWidth - 1;\r
560a435d 1432\r
1436aea4 1433 CopyMem ((UINT8 *)&Operand, Buffer, Question->StorageWidth);\r
560a435d
DB
1434\r
1435 RetVal = BitFieldWrite32 (Operand, StartBit, EndBit, Value);\r
1436\r
1436aea4 1437 CopyMem (Buffer, (UINT8 *)&RetVal, Question->StorageWidth);\r
560a435d
DB
1438}\r
1439\r
7a9612ce
ED
1440/**\r
1441 Convert the buffer value to HiiValue.\r
1442\r
1443 @param Question The question.\r
1444 @param Value Unicode buffer save the question value.\r
1445\r
1446 @retval Status whether convert the value success.\r
1447\r
1448**/\r
1449EFI_STATUS\r
1450BufferToValue (\r
1436aea4
MK
1451 IN OUT FORM_BROWSER_STATEMENT *Question,\r
1452 IN CHAR16 *Value\r
7a9612ce
ED
1453 )\r
1454{\r
1436aea4
MK
1455 CHAR16 *StringPtr;\r
1456 BOOLEAN IsBufferStorage;\r
1457 CHAR16 *DstBuf;\r
1458 CHAR16 TempChar;\r
1459 UINTN LengthStr;\r
1460 UINT8 *Dst;\r
1461 CHAR16 TemStr[5];\r
1462 UINTN Index;\r
1463 UINT8 DigitUint8;\r
1464 BOOLEAN IsString;\r
1465 UINTN Length;\r
1466 EFI_STATUS Status;\r
1467 UINT8 *Buffer;\r
560a435d
DB
1468\r
1469 Buffer = NULL;\r
7a9612ce 1470\r
1436aea4
MK
1471 IsString = (BOOLEAN)((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
1472 if ((Question->Storage->Type == EFI_HII_VARSTORE_BUFFER) ||\r
1473 (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))\r
1474 {\r
7a9612ce
ED
1475 IsBufferStorage = TRUE;\r
1476 } else {\r
1477 IsBufferStorage = FALSE;\r
1478 }\r
1479\r
1480 //\r
1481 // Question Value is provided by Buffer Storage or NameValue Storage\r
1482 //\r
1483 if (Question->BufferValue != NULL) {\r
1484 //\r
1485 // This Question is password or orderedlist\r
1486 //\r
1487 Dst = Question->BufferValue;\r
1488 } else {\r
1489 //\r
1490 // Other type of Questions\r
1491 //\r
560a435d
DB
1492 if (Question->QuestionReferToBitField) {\r
1493 Buffer = (UINT8 *)AllocateZeroPool (Question->StorageWidth);\r
66918edd
DB
1494 if (Buffer == NULL) {\r
1495 return EFI_OUT_OF_RESOURCES;\r
1496 }\r
1436aea4 1497\r
560a435d
DB
1498 Dst = Buffer;\r
1499 } else {\r
1436aea4 1500 Dst = (UINT8 *)&Question->HiiValue.Value;\r
560a435d 1501 }\r
7a9612ce
ED
1502 }\r
1503\r
1504 //\r
1505 // Temp cut at the end of this section, end with '\0' or '&'.\r
1506 //\r
1507 StringPtr = Value;\r
1508 while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
1509 StringPtr++;\r
1510 }\r
1436aea4
MK
1511\r
1512 TempChar = *StringPtr;\r
7a9612ce
ED
1513 *StringPtr = L'\0';\r
1514\r
1515 LengthStr = StrLen (Value);\r
f3587039
DB
1516\r
1517 //\r
1518 // Value points to a Unicode hexadecimal string, we need to convert the string to the value with CHAR16/UINT8...type.\r
1519 // When generating the Value string, we follow this rule: 1 byte -> 2 Unicode characters (for string: 2 byte(CHAR16) ->4 Unicode characters).\r
1520 // So the maximum value string length of a question is : Question->StorageWidth * 2.\r
1521 // If the value string length > Question->StorageWidth * 2, only set the string length as Question->StorageWidth * 2, then convert.\r
1522 //\r
1436aea4
MK
1523 if (LengthStr > (UINTN)Question->StorageWidth * 2) {\r
1524 Length = (UINTN)Question->StorageWidth * 2;\r
f3587039
DB
1525 } else {\r
1526 Length = LengthStr;\r
1527 }\r
1528\r
1436aea4 1529 Status = EFI_SUCCESS;\r
7a9612ce
ED
1530 if (!IsBufferStorage && IsString) {\r
1531 //\r
1532 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
1533 // Add string tail char L'\0' into Length\r
1534 //\r
1436aea4 1535 DstBuf = (CHAR16 *)Dst;\r
f3587039
DB
1536 ZeroMem (TemStr, sizeof (TemStr));\r
1537 for (Index = 0; Index < Length; Index += 4) {\r
1538 StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value + Index, 4);\r
1436aea4 1539 DstBuf[Index/4] = (CHAR16)StrHexToUint64 (TemStr);\r
7a9612ce 1540 }\r
1436aea4 1541\r
f3587039
DB
1542 //\r
1543 // Add tailing L'\0' character\r
1544 //\r
1545 DstBuf[Index/4] = L'\0';\r
7a9612ce 1546 } else {\r
f3587039 1547 ZeroMem (TemStr, sizeof (TemStr));\r
1436aea4
MK
1548 for (Index = 0; Index < Length; Index++) {\r
1549 TemStr[0] = Value[LengthStr - Index - 1];\r
1550 DigitUint8 = (UINT8)StrHexToUint64 (TemStr);\r
f3587039 1551 if ((Index & 1) == 0) {\r
1436aea4 1552 Dst[Index/2] = DigitUint8;\r
f3587039 1553 } else {\r
1436aea4 1554 Dst[Index/2] = (UINT8)((DigitUint8 << 4) + Dst[Index/2]);\r
7a9612ce
ED
1555 }\r
1556 }\r
1557 }\r
1558\r
1559 *StringPtr = TempChar;\r
1560\r
1436aea4 1561 if ((Buffer != NULL) && Question->QuestionReferToBitField) {\r
560a435d 1562 GetBitsQuestionValue (Question, Buffer);\r
66918edd 1563 FreePool (Buffer);\r
560a435d
DB
1564 }\r
1565\r
7a9612ce
ED
1566 return Status;\r
1567}\r
7936fb6a 1568\r
1569/**\r
1570 Get Question's current Value.\r
1571\r
1572 @param FormSet FormSet data structure.\r
1573 @param Form Form data structure.\r
1574 @param Question Question to be initialized.\r
816a7110 1575 @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.\r
7936fb6a 1576\r
1577 @retval EFI_SUCCESS The function completed successfully.\r
1578\r
1579**/\r
1580EFI_STATUS\r
1581GetQuestionValue (\r
1436aea4
MK
1582 IN FORM_BROWSER_FORMSET *FormSet,\r
1583 IN FORM_BROWSER_FORM *Form,\r
1584 IN OUT FORM_BROWSER_STATEMENT *Question,\r
1585 IN GET_SET_QUESTION_VALUE_WITH GetValueFrom\r
7936fb6a 1586 )\r
1587{\r
1588 EFI_STATUS Status;\r
1589 BOOLEAN Enabled;\r
1590 BOOLEAN Pending;\r
1591 UINT8 *Dst;\r
1592 UINTN StorageWidth;\r
1593 EFI_TIME EfiTime;\r
94f3aae7 1594 BROWSER_STORAGE *Storage;\r
a35ecb75 1595 FORMSET_STORAGE *FormsetStorage;\r
7936fb6a 1596 EFI_IFR_TYPE_VALUE *QuestionValue;\r
1597 CHAR16 *ConfigRequest;\r
1598 CHAR16 *Progress;\r
1599 CHAR16 *Result;\r
1600 CHAR16 *Value;\r
1601 UINTN Length;\r
1602 BOOLEAN IsBufferStorage;\r
5ad66ec6 1603 UINTN MaxLen;\r
7936fb6a 1604\r
1605 Status = EFI_SUCCESS;\r
cce6230f 1606 Value = NULL;\r
db40504e 1607 Result = NULL;\r
7936fb6a 1608\r
816a7110
ED
1609 if (GetValueFrom >= GetSetValueWithMax) {\r
1610 return EFI_INVALID_PARAMETER;\r
1611 }\r
1612\r
7936fb6a 1613 //\r
1614 // Question value is provided by an Expression, evaluate it\r
1615 //\r
1616 if (Question->ValueExpression != NULL) {\r
1617 Status = EvaluateExpression (FormSet, Form, Question->ValueExpression);\r
1618 if (!EFI_ERROR (Status)) {\r
901ba0e7
ED
1619 if (Question->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
1620 ASSERT (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER && Question->HiiValue.Buffer != NULL);\r
1621 if (Question->StorageWidth > Question->ValueExpression->Result.BufferLen) {\r
1622 CopyMem (Question->HiiValue.Buffer, Question->ValueExpression->Result.Buffer, Question->ValueExpression->Result.BufferLen);\r
1623 Question->HiiValue.BufferLen = Question->ValueExpression->Result.BufferLen;\r
1624 } else {\r
1625 CopyMem (Question->HiiValue.Buffer, Question->ValueExpression->Result.Buffer, Question->StorageWidth);\r
1626 Question->HiiValue.BufferLen = Question->StorageWidth;\r
1627 }\r
1436aea4 1628\r
901ba0e7
ED
1629 FreePool (Question->ValueExpression->Result.Buffer);\r
1630 }\r
1436aea4 1631\r
901ba0e7 1632 Question->HiiValue.Type = Question->ValueExpression->Result.Type;\r
d1102dba 1633 CopyMem (&Question->HiiValue.Value, &Question->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));\r
7936fb6a 1634 }\r
1436aea4 1635\r
7936fb6a 1636 return Status;\r
1637 }\r
d1102dba 1638\r
2573712e
LG
1639 //\r
1640 // Get question value by read expression.\r
1641 //\r
1436aea4 1642 if ((Question->ReadExpression != NULL) && (Form->FormType == STANDARD_MAP_FORM_TYPE)) {\r
2573712e 1643 Status = EvaluateExpression (FormSet, Form, Question->ReadExpression);\r
d1102dba 1644 if (!EFI_ERROR (Status) &&\r
1436aea4
MK
1645 ((Question->ReadExpression->Result.Type < EFI_IFR_TYPE_OTHER) || (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER)))\r
1646 {\r
2573712e
LG
1647 //\r
1648 // Only update question value to the valid result.\r
1649 //\r
901ba0e7
ED
1650 if (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
1651 ASSERT (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER && Question->HiiValue.Buffer != NULL);\r
1652 if (Question->StorageWidth > Question->ReadExpression->Result.BufferLen) {\r
1653 CopyMem (Question->HiiValue.Buffer, Question->ReadExpression->Result.Buffer, Question->ReadExpression->Result.BufferLen);\r
1654 Question->HiiValue.BufferLen = Question->ReadExpression->Result.BufferLen;\r
1655 } else {\r
1656 CopyMem (Question->HiiValue.Buffer, Question->ReadExpression->Result.Buffer, Question->StorageWidth);\r
1657 Question->HiiValue.BufferLen = Question->StorageWidth;\r
1658 }\r
1436aea4 1659\r
901ba0e7
ED
1660 FreePool (Question->ReadExpression->Result.Buffer);\r
1661 }\r
1436aea4 1662\r
901ba0e7 1663 Question->HiiValue.Type = Question->ReadExpression->Result.Type;\r
d1102dba 1664 CopyMem (&Question->HiiValue.Value, &Question->ReadExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));\r
2573712e
LG
1665 return EFI_SUCCESS;\r
1666 }\r
1667 }\r
7936fb6a 1668\r
1669 //\r
1670 // Question value is provided by RTC\r
1671 //\r
1436aea4 1672 Storage = Question->Storage;\r
7936fb6a 1673 QuestionValue = &Question->HiiValue.Value;\r
1674 if (Storage == NULL) {\r
1675 //\r
1676 // It's a Question without storage, or RTC date/time\r
1677 //\r
1436aea4 1678 if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {\r
7936fb6a 1679 //\r
1680 // Date and time define the same Flags bit\r
1681 //\r
1682 switch (Question->Flags & EFI_QF_DATE_STORAGE) {\r
1436aea4
MK
1683 case QF_DATE_STORAGE_TIME:\r
1684 Status = gRT->GetTime (&EfiTime, NULL);\r
1685 break;\r
7936fb6a 1686\r
1436aea4
MK
1687 case QF_DATE_STORAGE_WAKEUP:\r
1688 Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);\r
1689 break;\r
7936fb6a 1690\r
1436aea4
MK
1691 case QF_DATE_STORAGE_NORMAL:\r
1692 default:\r
1693 //\r
1694 // For date/time without storage\r
1695 //\r
1696 return EFI_SUCCESS;\r
7936fb6a 1697 }\r
1698\r
1699 if (EFI_ERROR (Status)) {\r
1436aea4 1700 if (Question->Operand == EFI_IFR_DATE_OP) {\r
cc63add8
DB
1701 QuestionValue->date.Year = 0xff;\r
1702 QuestionValue->date.Month = 0xff;\r
1703 QuestionValue->date.Day = 0xff;\r
1704 } else {\r
1705 QuestionValue->time.Hour = 0xff;\r
1706 QuestionValue->time.Minute = 0xff;\r
1707 QuestionValue->time.Second = 0xff;\r
1708 }\r
1436aea4 1709\r
cc63add8 1710 return EFI_SUCCESS;\r
7936fb6a 1711 }\r
1712\r
1713 if (Question->Operand == EFI_IFR_DATE_OP) {\r
1714 QuestionValue->date.Year = EfiTime.Year;\r
1715 QuestionValue->date.Month = EfiTime.Month;\r
1716 QuestionValue->date.Day = EfiTime.Day;\r
1717 } else {\r
1718 QuestionValue->time.Hour = EfiTime.Hour;\r
1719 QuestionValue->time.Minute = EfiTime.Minute;\r
1720 QuestionValue->time.Second = EfiTime.Second;\r
1721 }\r
1722 }\r
1723\r
1724 return EFI_SUCCESS;\r
1725 }\r
1726\r
1727 //\r
1728 // Question value is provided by EFI variable\r
1729 //\r
1730 StorageWidth = Question->StorageWidth;\r
1731 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
1732 if (Question->BufferValue != NULL) {\r
1733 Dst = Question->BufferValue;\r
1734 } else {\r
1436aea4 1735 Dst = (UINT8 *)QuestionValue;\r
7936fb6a 1736 }\r
1737\r
1738 Status = gRT->GetVariable (\r
1436aea4
MK
1739 Question->VariableName,\r
1740 &Storage->Guid,\r
1741 NULL,\r
1742 &StorageWidth,\r
1743 Dst\r
1744 );\r
7936fb6a 1745 //\r
1746 // Always return success, even this EFI variable doesn't exist\r
1747 //\r
1748 return EFI_SUCCESS;\r
1749 }\r
1750\r
1751 //\r
1752 // Question Value is provided by Buffer Storage or NameValue Storage\r
1753 //\r
1754 if (Question->BufferValue != NULL) {\r
1755 //\r
1756 // This Question is password or orderedlist\r
1757 //\r
1758 Dst = Question->BufferValue;\r
1759 } else {\r
1760 //\r
1761 // Other type of Questions\r
1762 //\r
1436aea4 1763 Dst = (UINT8 *)&Question->HiiValue.Value;\r
7936fb6a 1764 }\r
1765\r
1436aea4
MK
1766 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ||\r
1767 (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))\r
1768 {\r
cce6230f
ED
1769 IsBufferStorage = TRUE;\r
1770 } else {\r
1771 IsBufferStorage = FALSE;\r
1772 }\r
1436aea4
MK
1773\r
1774 if ((GetValueFrom == GetSetValueWithEditBuffer) || (GetValueFrom == GetSetValueWithBuffer)) {\r
7936fb6a 1775 if (IsBufferStorage) {\r
816a7110
ED
1776 if (GetValueFrom == GetSetValueWithEditBuffer) {\r
1777 //\r
1778 // Copy from storage Edit buffer\r
560a435d 1779 // If the Question refer to bit filed, get the value in the related bit filed.\r
816a7110 1780 //\r
560a435d
DB
1781 if (Question->QuestionReferToBitField) {\r
1782 GetBitsQuestionValue (Question, Storage->EditBuffer + Question->VarStoreInfo.VarOffset);\r
1783 } else {\r
1784 CopyMem (Dst, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
1785 }\r
816a7110
ED
1786 } else {\r
1787 //\r
1788 // Copy from storage Edit buffer\r
560a435d 1789 // If the Question refer to bit filed, get the value in the related bit filed.\r
816a7110 1790 //\r
560a435d
DB
1791 if (Question->QuestionReferToBitField) {\r
1792 GetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset);\r
1793 } else {\r
1794 CopyMem (Dst, Storage->Buffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
1795 }\r
816a7110 1796 }\r
7936fb6a 1797 } else {\r
1436aea4 1798 Value = NULL;\r
816a7110 1799 Status = GetValueByName (Storage, Question->VariableName, &Value, GetValueFrom);\r
7936fb6a 1800 if (EFI_ERROR (Status)) {\r
1801 return Status;\r
1802 }\r
d66e6c16 1803\r
1b2bf3ca 1804 ASSERT (Value != NULL);\r
7a9612ce 1805 Status = BufferToValue (Question, Value);\r
f4113e1f 1806 FreePool (Value);\r
7936fb6a 1807 }\r
1808 } else {\r
1436aea4 1809 FormsetStorage = GetFstStgFromVarId (FormSet, Question->VarStoreId);\r
a35ecb75 1810 ASSERT (FormsetStorage != NULL);\r
7248790e
ED
1811 //\r
1812 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
1813 // <ConfigHdr> + "&" + <VariableName>\r
1814 //\r
1815 if (IsBufferStorage) {\r
1436aea4 1816 Length = StrLen (FormsetStorage->ConfigHdr);\r
7248790e
ED
1817 Length += StrLen (Question->BlockName);\r
1818 } else {\r
1436aea4 1819 Length = StrLen (FormsetStorage->ConfigHdr);\r
7248790e
ED
1820 Length += StrLen (Question->VariableName) + 1;\r
1821 }\r
1436aea4 1822\r
5ad66ec6 1823 // Allocate buffer include '\0'\r
1436aea4 1824 MaxLen = Length + 1;\r
5ad66ec6 1825 ConfigRequest = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
7248790e 1826 ASSERT (ConfigRequest != NULL);\r
7936fb6a 1827\r
5ad66ec6 1828 StrCpyS (ConfigRequest, MaxLen, FormsetStorage->ConfigHdr);\r
7248790e 1829 if (IsBufferStorage) {\r
5ad66ec6 1830 StrCatS (ConfigRequest, MaxLen, Question->BlockName);\r
7248790e 1831 } else {\r
5ad66ec6
DB
1832 StrCatS (ConfigRequest, MaxLen, L"&");\r
1833 StrCatS (ConfigRequest, MaxLen, Question->VariableName);\r
7248790e 1834 }\r
7936fb6a 1835\r
7248790e
ED
1836 //\r
1837 // Request current settings from Configuration Driver\r
1838 //\r
1839 Status = mHiiConfigRouting->ExtractConfig (\r
1436aea4
MK
1840 mHiiConfigRouting,\r
1841 ConfigRequest,\r
1842 &Progress,\r
1843 &Result\r
1844 );\r
7248790e
ED
1845 FreePool (ConfigRequest);\r
1846 if (EFI_ERROR (Status)) {\r
1847 return Status;\r
1848 }\r
7936fb6a 1849\r
7248790e
ED
1850 //\r
1851 // Skip <ConfigRequest>\r
1852 //\r
1853 if (IsBufferStorage) {\r
1854 Value = StrStr (Result, L"&VALUE");\r
1855 if (Value == NULL) {\r
cce6230f
ED
1856 FreePool (Result);\r
1857 return EFI_NOT_FOUND;\r
1858 }\r
1436aea4 1859\r
cce6230f 1860 //\r
7248790e 1861 // Skip "&VALUE"\r
cce6230f 1862 //\r
7248790e
ED
1863 Value = Value + 6;\r
1864 } else {\r
1865 Value = Result + Length;\r
1866 }\r
1436aea4 1867\r
7248790e
ED
1868 if (*Value != '=') {\r
1869 FreePool (Result);\r
1870 return EFI_NOT_FOUND;\r
1871 }\r
1436aea4 1872\r
7248790e
ED
1873 //\r
1874 // Skip '=', point to value\r
1875 //\r
1876 Value = Value + 1;\r
1877\r
7a9612ce 1878 Status = BufferToValue (Question, Value);\r
7248790e
ED
1879 if (EFI_ERROR (Status)) {\r
1880 FreePool (Result);\r
1881 return Status;\r
63d55bb9
LG
1882 }\r
1883\r
7936fb6a 1884 //\r
1885 // Synchronize Edit Buffer\r
1886 //\r
1887 if (IsBufferStorage) {\r
1888 CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);\r
1889 } else {\r
7c6c064c 1890 SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer, NULL);\r
7936fb6a 1891 }\r
db40504e
ED
1892\r
1893 if (Result != NULL) {\r
1894 FreePool (Result);\r
1895 }\r
7936fb6a 1896 }\r
1897\r
1898 return Status;\r
1899}\r
1900\r
7936fb6a 1901/**\r
1902 Save Question Value to edit copy(cached) or Storage(uncached).\r
1903\r
1904 @param FormSet FormSet data structure.\r
1905 @param Form Form data structure.\r
1906 @param Question Pointer to the Question.\r
816a7110 1907 @param SetValueTo Update the question value to editbuffer , buffer or hii driver.\r
7936fb6a 1908\r
1909 @retval EFI_SUCCESS The function completed successfully.\r
1910\r
1911**/\r
1912EFI_STATUS\r
1913SetQuestionValue (\r
1436aea4
MK
1914 IN FORM_BROWSER_FORMSET *FormSet,\r
1915 IN FORM_BROWSER_FORM *Form,\r
1916 IN OUT FORM_BROWSER_STATEMENT *Question,\r
1917 IN GET_SET_QUESTION_VALUE_WITH SetValueTo\r
7936fb6a 1918 )\r
1919{\r
1920 EFI_STATUS Status;\r
1921 BOOLEAN Enabled;\r
1922 BOOLEAN Pending;\r
1923 UINT8 *Src;\r
1924 EFI_TIME EfiTime;\r
1925 UINTN BufferLen;\r
1926 UINTN StorageWidth;\r
94f3aae7 1927 BROWSER_STORAGE *Storage;\r
a35ecb75 1928 FORMSET_STORAGE *FormsetStorage;\r
7936fb6a 1929 EFI_IFR_TYPE_VALUE *QuestionValue;\r
1930 CHAR16 *ConfigResp;\r
1931 CHAR16 *Progress;\r
1932 CHAR16 *Value;\r
1933 UINTN Length;\r
1934 BOOLEAN IsBufferStorage;\r
1935 BOOLEAN IsString;\r
63d55bb9
LG
1936 UINT8 *TemBuffer;\r
1937 CHAR16 *TemName;\r
1938 CHAR16 *TemString;\r
1939 UINTN Index;\r
7c6c064c 1940 NAME_VALUE_NODE *Node;\r
5ad66ec6 1941 UINTN MaxLen;\r
7936fb6a 1942\r
1943 Status = EFI_SUCCESS;\r
7c6c064c 1944 Node = NULL;\r
7936fb6a 1945\r
816a7110
ED
1946 if (SetValueTo >= GetSetValueWithMax) {\r
1947 return EFI_INVALID_PARAMETER;\r
1948 }\r
1949\r
7936fb6a 1950 //\r
1951 // If Question value is provided by an Expression, then it is read only\r
1952 //\r
1953 if (Question->ValueExpression != NULL) {\r
1954 return Status;\r
1955 }\r
d1102dba 1956\r
2573712e
LG
1957 //\r
1958 // Before set question value, evaluate its write expression.\r
1959 //\r
1436aea4 1960 if ((Question->WriteExpression != NULL) && (Form->FormType == STANDARD_MAP_FORM_TYPE)) {\r
2573712e
LG
1961 Status = EvaluateExpression (FormSet, Form, Question->WriteExpression);\r
1962 if (EFI_ERROR (Status)) {\r
1963 return Status;\r
1964 }\r
1965 }\r
7936fb6a 1966\r
1967 //\r
1968 // Question value is provided by RTC\r
1969 //\r
1436aea4 1970 Storage = Question->Storage;\r
7936fb6a 1971 QuestionValue = &Question->HiiValue.Value;\r
1972 if (Storage == NULL) {\r
1973 //\r
1974 // It's a Question without storage, or RTC date/time\r
1975 //\r
1436aea4 1976 if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {\r
7936fb6a 1977 //\r
1978 // Date and time define the same Flags bit\r
1979 //\r
1980 switch (Question->Flags & EFI_QF_DATE_STORAGE) {\r
1436aea4
MK
1981 case QF_DATE_STORAGE_TIME:\r
1982 Status = gRT->GetTime (&EfiTime, NULL);\r
1983 break;\r
7936fb6a 1984\r
1436aea4
MK
1985 case QF_DATE_STORAGE_WAKEUP:\r
1986 Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);\r
1987 break;\r
7936fb6a 1988\r
1436aea4
MK
1989 case QF_DATE_STORAGE_NORMAL:\r
1990 default:\r
1991 //\r
1992 // For date/time without storage\r
1993 //\r
1994 return EFI_SUCCESS;\r
7936fb6a 1995 }\r
1996\r
1997 if (EFI_ERROR (Status)) {\r
1998 return Status;\r
1999 }\r
2000\r
2001 if (Question->Operand == EFI_IFR_DATE_OP) {\r
2002 EfiTime.Year = QuestionValue->date.Year;\r
2003 EfiTime.Month = QuestionValue->date.Month;\r
2004 EfiTime.Day = QuestionValue->date.Day;\r
2005 } else {\r
2006 EfiTime.Hour = QuestionValue->time.Hour;\r
2007 EfiTime.Minute = QuestionValue->time.Minute;\r
2008 EfiTime.Second = QuestionValue->time.Second;\r
2009 }\r
2010\r
2011 if ((Question->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_TIME) {\r
2012 Status = gRT->SetTime (&EfiTime);\r
2013 } else {\r
2014 Status = gRT->SetWakeupTime (TRUE, &EfiTime);\r
2015 }\r
2016 }\r
2017\r
2018 return Status;\r
2019 }\r
2020\r
2021 //\r
2022 // Question value is provided by EFI variable\r
2023 //\r
2024 StorageWidth = Question->StorageWidth;\r
2025 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
2026 if (Question->BufferValue != NULL) {\r
2027 Src = Question->BufferValue;\r
2028 } else {\r
1436aea4 2029 Src = (UINT8 *)QuestionValue;\r
7936fb6a 2030 }\r
2031\r
2032 Status = gRT->SetVariable (\r
1436aea4
MK
2033 Question->VariableName,\r
2034 &Storage->Guid,\r
2035 Storage->Attributes,\r
2036 StorageWidth,\r
2037 Src\r
2038 );\r
7936fb6a 2039 return Status;\r
2040 }\r
2041\r
2042 //\r
2043 // Question Value is provided by Buffer Storage or NameValue Storage\r
2044 //\r
2045 if (Question->BufferValue != NULL) {\r
2046 Src = Question->BufferValue;\r
2047 } else {\r
1436aea4 2048 Src = (UINT8 *)&Question->HiiValue.Value;\r
7936fb6a 2049 }\r
2050\r
1436aea4
MK
2051 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ||\r
2052 (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))\r
2053 {\r
cce6230f
ED
2054 IsBufferStorage = TRUE;\r
2055 } else {\r
2056 IsBufferStorage = FALSE;\r
2057 }\r
816a7110 2058\r
1436aea4
MK
2059 IsString = (BOOLEAN)((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
2060\r
2061 if ((SetValueTo == GetSetValueWithEditBuffer) || (SetValueTo == GetSetValueWithBuffer)) {\r
816a7110
ED
2062 if (IsBufferStorage) {\r
2063 if (SetValueTo == GetSetValueWithEditBuffer) {\r
2064 //\r
2065 // Copy to storage edit buffer\r
560a435d
DB
2066 // If the Question refer to bit filed, copy the value in related bit filed to storage edit buffer.\r
2067 //\r
2068 if (Question->QuestionReferToBitField) {\r
2069 SetBitsQuestionValue (Question, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, (UINT32)(*Src));\r
2070 } else {\r
2071 CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
2072 }\r
816a7110
ED
2073 } else if (SetValueTo == GetSetValueWithBuffer) {\r
2074 //\r
560a435d
DB
2075 // Copy to storage buffer\r
2076 // If the Question refer to bit filed, copy the value in related bit filed to storage buffer.\r
2077 //\r
2078 if (Question->QuestionReferToBitField) {\r
2079 SetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset, (UINT32)(*Src));\r
2080 } else {\r
2081 CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
2082 }\r
63d55bb9 2083 }\r
7936fb6a 2084 } else {\r
816a7110
ED
2085 if (IsString) {\r
2086 //\r
2087 // Allocate enough string buffer.\r
2088 //\r
1436aea4
MK
2089 Value = NULL;\r
2090 BufferLen = ((StrLen ((CHAR16 *)Src) * 4) + 1) * sizeof (CHAR16);\r
2091 Value = AllocateZeroPool (BufferLen);\r
816a7110
ED
2092 ASSERT (Value != NULL);\r
2093 //\r
2094 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
2095 //\r
1436aea4 2096 TemName = (CHAR16 *)Src;\r
816a7110 2097 TemString = Value;\r
1436aea4 2098 for ( ; *TemName != L'\0'; TemName++) {\r
9f4048f7
HW
2099 UnicodeValueToStringS (\r
2100 TemString,\r
2101 BufferLen - ((UINTN)TemString - (UINTN)Value),\r
2102 PREFIX_ZERO | RADIX_HEX,\r
2103 *TemName,\r
2104 4\r
2105 );\r
2106 TemString += StrnLenS (TemString, (BufferLen - ((UINTN)TemString - (UINTN)Value)) / sizeof (CHAR16));\r
816a7110
ED
2107 }\r
2108 } else {\r
2109 BufferLen = StorageWidth * 2 + 1;\r
1436aea4 2110 Value = AllocateZeroPool (BufferLen * sizeof (CHAR16));\r
816a7110
ED
2111 ASSERT (Value != NULL);\r
2112 //\r
2113 // Convert Buffer to Hex String\r
2114 //\r
2115 TemBuffer = Src + StorageWidth - 1;\r
2116 TemString = Value;\r
1436aea4 2117 for (Index = 0; Index < StorageWidth; Index++, TemBuffer--) {\r
9f4048f7
HW
2118 UnicodeValueToStringS (\r
2119 TemString,\r
2120 BufferLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)Value),\r
2121 PREFIX_ZERO | RADIX_HEX,\r
2122 *TemBuffer,\r
2123 2\r
2124 );\r
2125 TemString += StrnLenS (TemString, BufferLen - ((UINTN)TemString - (UINTN)Value) / sizeof (CHAR16));\r
816a7110 2126 }\r
63d55bb9 2127 }\r
7936fb6a 2128\r
7c6c064c 2129 Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo, &Node);\r
816a7110 2130 FreePool (Value);\r
7c6c064c
ED
2131 if (EFI_ERROR (Status)) {\r
2132 return Status;\r
2133 }\r
816a7110
ED
2134 }\r
2135 } else if (SetValueTo == GetSetValueWithHiiDriver) {\r
7248790e
ED
2136 //\r
2137 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||\r
2138 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"\r
2139 //\r
2140 if (IsBufferStorage) {\r
2141 Length = StrLen (Question->BlockName) + 7;\r
2142 } else {\r
2143 Length = StrLen (Question->VariableName) + 2;\r
2144 }\r
1436aea4 2145\r
7248790e 2146 if (!IsBufferStorage && IsString) {\r
1436aea4 2147 Length += (StrLen ((CHAR16 *)Src) * 4);\r
7248790e
ED
2148 } else {\r
2149 Length += (StorageWidth * 2);\r
2150 }\r
1436aea4
MK
2151\r
2152 FormsetStorage = GetFstStgFromVarId (FormSet, Question->VarStoreId);\r
a35ecb75 2153 ASSERT (FormsetStorage != NULL);\r
1436aea4 2154 MaxLen = StrLen (FormsetStorage->ConfigHdr) + Length + 1;\r
5ad66ec6 2155 ConfigResp = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
7248790e 2156 ASSERT (ConfigResp != NULL);\r
7936fb6a 2157\r
5ad66ec6 2158 StrCpyS (ConfigResp, MaxLen, FormsetStorage->ConfigHdr);\r
7248790e 2159 if (IsBufferStorage) {\r
5ad66ec6
DB
2160 StrCatS (ConfigResp, MaxLen, Question->BlockName);\r
2161 StrCatS (ConfigResp, MaxLen, L"&VALUE=");\r
7248790e 2162 } else {\r
5ad66ec6
DB
2163 StrCatS (ConfigResp, MaxLen, L"&");\r
2164 StrCatS (ConfigResp, MaxLen, Question->VariableName);\r
2165 StrCatS (ConfigResp, MaxLen, L"=");\r
7248790e 2166 }\r
cce6230f 2167\r
7248790e 2168 Value = ConfigResp + StrLen (ConfigResp);\r
63d55bb9 2169\r
7248790e 2170 if (!IsBufferStorage && IsString) {\r
7936fb6a 2171 //\r
7248790e 2172 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
7936fb6a 2173 //\r
1436aea4 2174 TemName = (CHAR16 *)Src;\r
7248790e 2175 TemString = Value;\r
1436aea4 2176 for ( ; *TemName != L'\0'; TemName++) {\r
9f4048f7
HW
2177 UnicodeValueToStringS (\r
2178 TemString,\r
2179 MaxLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ConfigResp),\r
2180 PREFIX_ZERO | RADIX_HEX,\r
2181 *TemName,\r
2182 4\r
2183 );\r
2184 TemString += StrnLenS (TemString, MaxLen - ((UINTN)TemString - (UINTN)ConfigResp) / sizeof (CHAR16));\r
63d55bb9 2185 }\r
7248790e 2186 } else {\r
63d55bb9 2187 //\r
7248790e 2188 // Convert Buffer to Hex String\r
63d55bb9 2189 //\r
7248790e
ED
2190 TemBuffer = Src + StorageWidth - 1;\r
2191 TemString = Value;\r
1436aea4 2192 for (Index = 0; Index < StorageWidth; Index++, TemBuffer--) {\r
9f4048f7
HW
2193 UnicodeValueToStringS (\r
2194 TemString,\r
2195 MaxLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ConfigResp),\r
2196 PREFIX_ZERO | RADIX_HEX,\r
2197 *TemBuffer,\r
2198 2\r
2199 );\r
2200 TemString += StrnLenS (TemString, MaxLen - ((UINTN)TemString - (UINTN)ConfigResp) / sizeof (CHAR16));\r
63d55bb9 2201 }\r
7248790e
ED
2202 }\r
2203\r
2204 //\r
2205 // Convert to lower char.\r
2206 //\r
2207 for (TemString = Value; *Value != L'\0'; Value++) {\r
1436aea4
MK
2208 if ((*Value >= L'A') && (*Value <= L'Z')) {\r
2209 *Value = (CHAR16)(*Value - L'A' + L'a');\r
7936fb6a 2210 }\r
2211 }\r
7248790e
ED
2212\r
2213 //\r
2214 // Submit Question Value to Configuration Driver\r
2215 //\r
2216 Status = mHiiConfigRouting->RouteConfig (\r
1436aea4
MK
2217 mHiiConfigRouting,\r
2218 ConfigResp,\r
2219 &Progress\r
2220 );\r
7248790e
ED
2221 if (EFI_ERROR (Status)) {\r
2222 FreePool (ConfigResp);\r
2223 return Status;\r
2224 }\r
1436aea4 2225\r
7248790e 2226 FreePool (ConfigResp);\r
d1102dba 2227\r
7936fb6a 2228 //\r
cce6230f 2229 // Sync storage, from editbuffer to buffer.\r
7936fb6a 2230 //\r
cce6230f 2231 CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
7936fb6a 2232 }\r
2233\r
2234 return Status;\r
2235}\r
2236\r
7936fb6a 2237/**\r
7c6c064c 2238 Perform nosubmitif check for a Form.\r
7936fb6a 2239\r
2240 @param FormSet FormSet data structure.\r
2241 @param Form Form data structure.\r
2242 @param Question The Question to be validated.\r
7c6c064c 2243 @param Type Validation type: NoSubmit\r
7936fb6a 2244\r
2245 @retval EFI_SUCCESS Form validation pass.\r
2246 @retval other Form validation failed.\r
2247\r
2248**/\r
2249EFI_STATUS\r
2250ValidateQuestion (\r
1436aea4
MK
2251 IN FORM_BROWSER_FORMSET *FormSet,\r
2252 IN FORM_BROWSER_FORM *Form,\r
2253 IN FORM_BROWSER_STATEMENT *Question,\r
2254 IN UINTN Type\r
7936fb6a 2255 )\r
2256{\r
1436aea4
MK
2257 EFI_STATUS Status;\r
2258 LIST_ENTRY *Link;\r
2259 LIST_ENTRY *ListHead;\r
2260 FORM_EXPRESSION *Expression;\r
2261 UINT32 BrowserStatus;\r
2262 CHAR16 *ErrorStr;\r
bfae1330
ED
2263\r
2264 BrowserStatus = BROWSER_SUCCESS;\r
2265 ErrorStr = NULL;\r
2266\r
2267 switch (Type) {\r
1436aea4
MK
2268 case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
2269 ListHead = &Question->InconsistentListHead;\r
2270 break;\r
7936fb6a 2271\r
1436aea4
MK
2272 case EFI_HII_EXPRESSION_WARNING_IF:\r
2273 ListHead = &Question->WarningListHead;\r
2274 break;\r
bfae1330 2275\r
1436aea4
MK
2276 case EFI_HII_EXPRESSION_NO_SUBMIT_IF:\r
2277 ListHead = &Question->NoSubmitListHead;\r
2278 break;\r
bfae1330 2279\r
1436aea4
MK
2280 default:\r
2281 ASSERT (FALSE);\r
2282 return EFI_UNSUPPORTED;\r
7936fb6a 2283 }\r
2284\r
2285 Link = GetFirstNode (ListHead);\r
2286 while (!IsNull (ListHead, Link)) {\r
2287 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
2288\r
2289 //\r
2290 // Evaluate the expression\r
2291 //\r
2292 Status = EvaluateExpression (FormSet, Form, Expression);\r
2293 if (EFI_ERROR (Status)) {\r
2294 return Status;\r
2295 }\r
2296\r
e6106e89 2297 if (IsTrue (&Expression->Result)) {\r
bfae1330 2298 switch (Type) {\r
1436aea4
MK
2299 case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
2300 BrowserStatus = BROWSER_INCONSISTENT_IF;\r
2301 break;\r
bfae1330 2302\r
1436aea4
MK
2303 case EFI_HII_EXPRESSION_WARNING_IF:\r
2304 BrowserStatus = BROWSER_WARNING_IF;\r
2305 break;\r
bfae1330 2306\r
1436aea4
MK
2307 case EFI_HII_EXPRESSION_NO_SUBMIT_IF:\r
2308 BrowserStatus = BROWSER_NO_SUBMIT_IF;\r
2309 //\r
2310 // This code only used to compatible with old display engine,\r
2311 // New display engine will not use this field.\r
2312 //\r
2313 if (Expression->Error != 0) {\r
2314 ErrorStr = GetToken (Expression->Error, FormSet->HiiHandle);\r
2315 }\r
bfae1330 2316\r
1436aea4
MK
2317 break;\r
2318\r
2319 default:\r
2320 ASSERT (FALSE);\r
2321 break;\r
7936fb6a 2322 }\r
2323\r
4d4deaac
ED
2324 if (!((Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) && mSystemSubmit)) {\r
2325 //\r
2326 // If in system submit process and for no_submit_if check, not popup this error message.\r
2327 // Will process this fail again later in not system submit process.\r
2328 //\r
1436aea4 2329 PopupErrorMessage (BrowserStatus, FormSet->HiiHandle, Expression->OpCode, ErrorStr);\r
4d4deaac 2330 }\r
bfae1330
ED
2331\r
2332 if (ErrorStr != NULL) {\r
2333 FreePool (ErrorStr);\r
2334 }\r
2335\r
2336 if (Type == EFI_HII_EXPRESSION_WARNING_IF) {\r
2337 return EFI_SUCCESS;\r
2338 } else {\r
2339 return EFI_NOT_READY;\r
2340 }\r
7936fb6a 2341 }\r
2342\r
2343 Link = GetNextNode (ListHead, Link);\r
2344 }\r
2345\r
2346 return EFI_SUCCESS;\r
2347}\r
2348\r
bfae1330 2349/**\r
d1102dba
LG
2350 Perform question check.\r
2351\r
2352 If one question has more than one check, process form high priority to low.\r
bfae1330
ED
2353 Only one error info will be popup.\r
2354\r
2355 @param FormSet FormSet data structure.\r
2356 @param Form Form data structure.\r
2357 @param Question The Question to be validated.\r
2358\r
2359 @retval EFI_SUCCESS Form validation pass.\r
2360 @retval other Form validation failed.\r
2361\r
2362**/\r
2363EFI_STATUS\r
2364ValueChangedValidation (\r
1436aea4
MK
2365 IN FORM_BROWSER_FORMSET *FormSet,\r
2366 IN FORM_BROWSER_FORM *Form,\r
2367 IN FORM_BROWSER_STATEMENT *Question\r
bfae1330
ED
2368 )\r
2369{\r
1436aea4 2370 EFI_STATUS Status;\r
bfae1330
ED
2371\r
2372 Status = EFI_SUCCESS;\r
2373\r
2374 //\r
2375 // Do the inconsistentif check.\r
2376 //\r
2377 if (!IsListEmpty (&Question->InconsistentListHead)) {\r
2378 Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
2379 if (EFI_ERROR (Status)) {\r
2380 return Status;\r
2381 }\r
2382 }\r
2383\r
2384 //\r
2385 // Do the warningif check.\r
2386 //\r
2387 if (!IsListEmpty (&Question->WarningListHead)) {\r
2388 Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_WARNING_IF);\r
2389 }\r
2390\r
2391 return Status;\r
2392}\r
7936fb6a 2393\r
2394/**\r
5adb8db7 2395 Perform NoSubmit check for each Form in FormSet.\r
7936fb6a 2396\r
2397 @param FormSet FormSet data structure.\r
b18e7050 2398 @param CurrentForm Current input form data structure.\r
4d4deaac 2399 @param Statement The statement for this check.\r
7936fb6a 2400\r
2401 @retval EFI_SUCCESS Form validation pass.\r
2402 @retval other Form validation failed.\r
2403\r
2404**/\r
2405EFI_STATUS\r
2406NoSubmitCheck (\r
1436aea4
MK
2407 IN FORM_BROWSER_FORMSET *FormSet,\r
2408 IN OUT FORM_BROWSER_FORM **CurrentForm,\r
2409 OUT FORM_BROWSER_STATEMENT **Statement\r
7936fb6a 2410 )\r
2411{\r
2412 EFI_STATUS Status;\r
2413 LIST_ENTRY *Link;\r
2414 FORM_BROWSER_STATEMENT *Question;\r
5adb8db7
LG
2415 FORM_BROWSER_FORM *Form;\r
2416 LIST_ENTRY *LinkForm;\r
7936fb6a 2417\r
5adb8db7
LG
2418 LinkForm = GetFirstNode (&FormSet->FormListHead);\r
2419 while (!IsNull (&FormSet->FormListHead, LinkForm)) {\r
1436aea4 2420 Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);\r
b18e7050
ED
2421 LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);\r
2422\r
1436aea4 2423 if ((*CurrentForm != NULL) && (*CurrentForm != Form)) {\r
b18e7050
ED
2424 continue;\r
2425 }\r
7936fb6a 2426\r
5adb8db7
LG
2427 Link = GetFirstNode (&Form->StatementListHead);\r
2428 while (!IsNull (&Form->StatementListHead, Link)) {\r
2429 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1436aea4 2430 Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF);\r
5adb8db7 2431 if (EFI_ERROR (Status)) {\r
4d4deaac
ED
2432 if (*CurrentForm == NULL) {\r
2433 *CurrentForm = Form;\r
2434 }\r
1436aea4 2435\r
4d4deaac
ED
2436 if (Statement != NULL) {\r
2437 *Statement = Question;\r
2438 }\r
1436aea4 2439\r
5adb8db7
LG
2440 return Status;\r
2441 }\r
2442\r
2443 Link = GetNextNode (&Form->StatementListHead, Link);\r
7936fb6a 2444 }\r
7936fb6a 2445 }\r
2446\r
2447 return EFI_SUCCESS;\r
2448}\r
2449\r
7936fb6a 2450/**\r
b18e7050
ED
2451 Fill storage's edit copy with settings requested from Configuration Driver.\r
2452\r
7c6c064c
ED
2453 @param Storage The storage which need to sync.\r
2454 @param ConfigRequest The config request string which used to sync storage.\r
d1102dba 2455 @param SyncOrRestore Sync the buffer to editbuffer or Restore the\r
cce6230f
ED
2456 editbuffer to buffer\r
2457 if TRUE, copy the editbuffer to the buffer.\r
2458 if FALSE, copy the buffer to the editbuffer.\r
b18e7050
ED
2459\r
2460 @retval EFI_SUCCESS The function completed successfully.\r
2461\r
2462**/\r
2463EFI_STATUS\r
7c6c064c 2464SynchronizeStorage (\r
1436aea4
MK
2465 OUT BROWSER_STORAGE *Storage,\r
2466 IN CHAR16 *ConfigRequest,\r
2467 IN BOOLEAN SyncOrRestore\r
b18e7050
ED
2468 )\r
2469{\r
1436aea4
MK
2470 EFI_STATUS Status;\r
2471 EFI_STRING Progress;\r
2472 EFI_STRING Result;\r
2473 UINTN BufferSize;\r
2474 LIST_ENTRY *Link;\r
2475 NAME_VALUE_NODE *Node;\r
2476 UINT8 *Src;\r
2477 UINT8 *Dst;\r
b18e7050
ED
2478\r
2479 Status = EFI_SUCCESS;\r
2480 Result = NULL;\r
25361615 2481\r
1436aea4
MK
2482 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ||\r
2483 (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER))\r
2484 {\r
7c6c064c 2485 BufferSize = Storage->Size;\r
cce6230f
ED
2486\r
2487 if (SyncOrRestore) {\r
7c6c064c
ED
2488 Src = Storage->EditBuffer;\r
2489 Dst = Storage->Buffer;\r
cce6230f 2490 } else {\r
7c6c064c
ED
2491 Src = Storage->Buffer;\r
2492 Dst = Storage->EditBuffer;\r
cce6230f
ED
2493 }\r
2494\r
7c6c064c 2495 if (ConfigRequest != NULL) {\r
1436aea4 2496 Status = mHiiConfigRouting->BlockToConfig (\r
7c6c064c
ED
2497 mHiiConfigRouting,\r
2498 ConfigRequest,\r
2499 Src,\r
2500 BufferSize,\r
2501 &Result,\r
2502 &Progress\r
2503 );\r
2504 if (EFI_ERROR (Status)) {\r
2505 return Status;\r
2506 }\r
b18e7050 2507\r
7c6c064c
ED
2508 Status = mHiiConfigRouting->ConfigToBlock (\r
2509 mHiiConfigRouting,\r
2510 Result,\r
2511 Dst,\r
2512 &BufferSize,\r
2513 &Progress\r
2514 );\r
2515 if (Result != NULL) {\r
2516 FreePool (Result);\r
2517 }\r
2518 } else {\r
2519 CopyMem (Dst, Src, BufferSize);\r
b18e7050 2520 }\r
7c6c064c
ED
2521 } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
2522 Link = GetFirstNode (&Storage->NameValueListHead);\r
2523 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
b18e7050
ED
2524 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
2525\r
1436aea4
MK
2526 if (((ConfigRequest != NULL) && (StrStr (ConfigRequest, Node->Name) != NULL)) ||\r
2527 (ConfigRequest == NULL))\r
2528 {\r
cce6230f
ED
2529 if (SyncOrRestore) {\r
2530 NewStringCpy (&Node->Value, Node->EditValue);\r
2531 } else {\r
2532 NewStringCpy (&Node->EditValue, Node->Value);\r
b18e7050 2533 }\r
b18e7050
ED
2534 }\r
2535\r
7c6c064c 2536 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
b18e7050
ED
2537 }\r
2538 }\r
2539\r
2540 return Status;\r
2541}\r
2542\r
816a7110
ED
2543/**\r
2544 When discard the question value, call the callback function with Changed type\r
2545 to inform the hii driver.\r
2546\r
2547 @param FormSet FormSet data structure.\r
2548 @param Form Form data structure.\r
2549\r
2550**/\r
2551VOID\r
2552SendDiscardInfoToDriver (\r
1436aea4
MK
2553 IN FORM_BROWSER_FORMSET *FormSet,\r
2554 IN FORM_BROWSER_FORM *Form\r
816a7110
ED
2555 )\r
2556{\r
2557 LIST_ENTRY *Link;\r
2558 FORM_BROWSER_STATEMENT *Question;\r
816a7110
ED
2559 EFI_IFR_TYPE_VALUE *TypeValue;\r
2560 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
2561\r
70f1d5e7
ED
2562 if (FormSet->ConfigAccess == NULL) {\r
2563 return;\r
2564 }\r
2565\r
816a7110
ED
2566 Link = GetFirstNode (&Form->StatementListHead);\r
2567 while (!IsNull (&Form->StatementListHead, Link)) {\r
2568 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1436aea4 2569 Link = GetNextNode (&Form->StatementListHead, Link);\r
816a7110 2570\r
1436aea4 2571 if ((Question->Storage == NULL) || (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
816a7110
ED
2572 continue;\r
2573 }\r
2574\r
e213ae45
ED
2575 if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
2576 continue;\r
2577 }\r
2578\r
816a7110
ED
2579 if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
2580 continue;\r
2581 }\r
2582\r
7c6c064c 2583 if (!Question->ValueChanged) {\r
816a7110
ED
2584 continue;\r
2585 }\r
2586\r
737adca3
ED
2587 //\r
2588 // Restore the question value before call the CHANGED callback type.\r
2589 //\r
2590 GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
2591\r
1436aea4
MK
2592 if (Question->Operand == EFI_IFR_STRING_OP) {\r
2593 HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16 *)Question->BufferValue, NULL);\r
cb312fb1
DB
2594 }\r
2595\r
816a7110 2596 if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
1436aea4 2597 TypeValue = (EFI_IFR_TYPE_VALUE *)Question->BufferValue;\r
816a7110
ED
2598 } else {\r
2599 TypeValue = &Question->HiiValue.Value;\r
2600 }\r
2601\r
2602 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
2603 FormSet->ConfigAccess->Callback (\r
2604 FormSet->ConfigAccess,\r
2605 EFI_BROWSER_ACTION_CHANGED,\r
2606 Question->QuestionId,\r
2607 Question->HiiValue.Type,\r
2608 TypeValue,\r
2609 &ActionRequest\r
2610 );\r
2611 }\r
2612}\r
b18e7050 2613\r
3cb44c20
DB
2614/**\r
2615 When submit the question value, call the callback function with Submitted type\r
2616 to inform the hii driver.\r
2617\r
2618 @param FormSet FormSet data structure.\r
2619 @param Form Form data structure.\r
2620\r
2621**/\r
2622VOID\r
2623SubmitCallbackForForm (\r
1436aea4
MK
2624 IN FORM_BROWSER_FORMSET *FormSet,\r
2625 IN FORM_BROWSER_FORM *Form\r
3cb44c20
DB
2626 )\r
2627{\r
2628 LIST_ENTRY *Link;\r
2629 FORM_BROWSER_STATEMENT *Question;\r
2630 EFI_IFR_TYPE_VALUE *TypeValue;\r
2631 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
2632\r
2633 if (FormSet->ConfigAccess == NULL) {\r
2634 return;\r
2635 }\r
2636\r
2637 Link = GetFirstNode (&Form->StatementListHead);\r
2638 while (!IsNull (&Form->StatementListHead, Link)) {\r
2639 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1436aea4 2640 Link = GetNextNode (&Form->StatementListHead, Link);\r
3cb44c20 2641\r
1436aea4 2642 if ((Question->Storage == NULL) || (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
3cb44c20
DB
2643 continue;\r
2644 }\r
2645\r
2646 if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
1436aea4 2647 continue;\r
3cb44c20
DB
2648 }\r
2649\r
2650 if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
1436aea4 2651 continue;\r
3cb44c20
DB
2652 }\r
2653\r
2654 if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
1436aea4 2655 TypeValue = (EFI_IFR_TYPE_VALUE *)Question->BufferValue;\r
3cb44c20
DB
2656 } else {\r
2657 TypeValue = &Question->HiiValue.Value;\r
2658 }\r
2659\r
2660 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
2661 FormSet->ConfigAccess->Callback (\r
2662 FormSet->ConfigAccess,\r
2663 EFI_BROWSER_ACTION_SUBMITTED,\r
2664 Question->QuestionId,\r
2665 Question->HiiValue.Type,\r
2666 TypeValue,\r
2667 &ActionRequest\r
2668 );\r
2669 }\r
2670}\r
2671\r
2672/**\r
2673 When value set Success, call the submit callback function.\r
2674\r
2675 @param FormSet FormSet data structure.\r
2676 @param Form Form data structure.\r
2677\r
2678**/\r
2679VOID\r
2680SubmitCallback (\r
1436aea4
MK
2681 IN FORM_BROWSER_FORMSET *FormSet,\r
2682 IN FORM_BROWSER_FORM *Form\r
3cb44c20
DB
2683 )\r
2684{\r
1436aea4
MK
2685 FORM_BROWSER_FORM *CurrentForm;\r
2686 LIST_ENTRY *Link;\r
3cb44c20
DB
2687\r
2688 if (Form != NULL) {\r
1436aea4 2689 SubmitCallbackForForm (FormSet, Form);\r
3cb44c20
DB
2690 return;\r
2691 }\r
2692\r
2693 Link = GetFirstNode (&FormSet->FormListHead);\r
2694 while (!IsNull (&FormSet->FormListHead, Link)) {\r
2695 CurrentForm = FORM_BROWSER_FORM_FROM_LINK (Link);\r
1436aea4 2696 Link = GetNextNode (&FormSet->FormListHead, Link);\r
3cb44c20 2697\r
1436aea4 2698 SubmitCallbackForForm (FormSet, CurrentForm);\r
3cb44c20
DB
2699 }\r
2700}\r
2701\r
938baa1f 2702/**\r
dcca25d1 2703 Validate the HiiHandle.\r
938baa1f 2704\r
dcca25d1 2705 @param HiiHandle The input HiiHandle which need to validate.\r
938baa1f
ED
2706\r
2707 @retval TRUE The handle is validate.\r
2708 @retval FALSE The handle is invalidate.\r
2709\r
2710**/\r
2711BOOLEAN\r
93551a01 2712ValidateHiiHandle (\r
1436aea4 2713 EFI_HII_HANDLE HiiHandle\r
938baa1f
ED
2714 )\r
2715{\r
1436aea4
MK
2716 EFI_HII_HANDLE *HiiHandles;\r
2717 UINTN Index;\r
2718 BOOLEAN Find;\r
938baa1f 2719\r
93551a01
ED
2720 if (HiiHandle == NULL) {\r
2721 return FALSE;\r
2722 }\r
2723\r
938baa1f 2724 Find = FALSE;\r
93551a01 2725\r
938baa1f
ED
2726 HiiHandles = HiiGetHiiHandles (NULL);\r
2727 ASSERT (HiiHandles != NULL);\r
2728\r
938baa1f 2729 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
93551a01 2730 if (HiiHandles[Index] == HiiHandle) {\r
938baa1f
ED
2731 Find = TRUE;\r
2732 break;\r
2733 }\r
2734 }\r
2735\r
93551a01
ED
2736 FreePool (HiiHandles);\r
2737\r
2738 return Find;\r
2739}\r
2740\r
2741/**\r
2742 Validate the FormSet. If the formset is not validate, remove it from the list.\r
2743\r
2744 @param FormSet The input FormSet which need to validate.\r
2745\r
2746 @retval TRUE The handle is validate.\r
2747 @retval FALSE The handle is invalidate.\r
2748\r
2749**/\r
2750BOOLEAN\r
2751ValidateFormSet (\r
1436aea4 2752 FORM_BROWSER_FORMSET *FormSet\r
93551a01
ED
2753 )\r
2754{\r
2755 BOOLEAN Find;\r
2756\r
2757 ASSERT (FormSet != NULL);\r
2758\r
1436aea4 2759 Find = ValidateHiiHandle (FormSet->HiiHandle);\r
275ea01e
ED
2760 //\r
2761 // Should not remove the formset which is being used.\r
2762 //\r
2763 if (!Find && (FormSet != gCurrentSelection->FormSet)) {\r
1436aea4 2764 CleanBrowserStorage (FormSet);\r
938baa1f
ED
2765 RemoveEntryList (&FormSet->Link);\r
2766 DestroyFormSet (FormSet);\r
2767 }\r
2768\r
938baa1f
ED
2769 return Find;\r
2770}\r
1436aea4 2771\r
7c6c064c
ED
2772/**\r
2773 Check whether need to enable the reset flag in form level.\r
2774 Also clean all ValueChanged flag in question.\r
2775\r
2776 @param SetFlag Whether need to set the Reset Flag.\r
4d4deaac 2777 @param FormSet FormSet data structure.\r
7c6c064c
ED
2778 @param Form Form data structure.\r
2779\r
2780**/\r
2781VOID\r
2782UpdateFlagForForm (\r
1436aea4
MK
2783 IN BOOLEAN SetFlag,\r
2784 IN FORM_BROWSER_FORMSET *FormSet,\r
2785 IN FORM_BROWSER_FORM *Form\r
7c6c064c
ED
2786 )\r
2787{\r
2788 LIST_ENTRY *Link;\r
2789 FORM_BROWSER_STATEMENT *Question;\r
4d4deaac 2790 BOOLEAN OldValue;\r
7c6c064c 2791\r
7c6c064c
ED
2792 Link = GetFirstNode (&Form->StatementListHead);\r
2793 while (!IsNull (&Form->StatementListHead, Link)) {\r
2794 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1436aea4 2795 Link = GetNextNode (&Form->StatementListHead, Link);\r
7c6c064c 2796\r
4d4deaac
ED
2797 if (!Question->ValueChanged) {\r
2798 continue;\r
7c6c064c 2799 }\r
4d4deaac
ED
2800\r
2801 OldValue = Question->ValueChanged;\r
2802\r
2803 //\r
2804 // Compare the buffer and editbuffer data to see whether the data has been saved.\r
2805 //\r
1436aea4 2806 Question->ValueChanged = IsQuestionValueChanged (FormSet, Form, Question, GetSetValueWithBothBuffer);\r
4d4deaac
ED
2807\r
2808 //\r
2809 // Only the changed data has been saved, then need to set the reset flag.\r
2810 //\r
f2e7732e
ED
2811 if (SetFlag && OldValue && !Question->ValueChanged) {\r
2812 if ((Question->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0) {\r
1436aea4 2813 gResetRequiredFormLevel = TRUE;\r
b2dcae4c 2814 gResetRequiredSystemLevel = TRUE;\r
f2e7732e
ED
2815 }\r
2816\r
2817 if ((Question->QuestionFlags & EFI_IFR_FLAG_RECONNECT_REQUIRED) != 0) {\r
2818 gFlagReconnect = TRUE;\r
2819 }\r
d1102dba 2820 }\r
7c6c064c
ED
2821 }\r
2822}\r
2823\r
2824/**\r
2825 Check whether need to enable the reset flag.\r
2826 Also clean ValueChanged flag for all statements.\r
2827\r
2828 Form level or formset level, only one.\r
d1102dba 2829\r
7c6c064c
ED
2830 @param SetFlag Whether need to set the Reset Flag.\r
2831 @param FormSet FormSet data structure.\r
2832 @param Form Form data structure.\r
2833\r
2834**/\r
2835VOID\r
2836ValueChangeResetFlagUpdate (\r
1436aea4
MK
2837 IN BOOLEAN SetFlag,\r
2838 IN FORM_BROWSER_FORMSET *FormSet,\r
2839 IN FORM_BROWSER_FORM *Form\r
7c6c064c
ED
2840 )\r
2841{\r
1436aea4
MK
2842 FORM_BROWSER_FORM *CurrentForm;\r
2843 LIST_ENTRY *Link;\r
7c6c064c 2844\r
7c6c064c 2845 if (Form != NULL) {\r
1436aea4 2846 UpdateFlagForForm (SetFlag, FormSet, Form);\r
7c6c064c
ED
2847 return;\r
2848 }\r
2849\r
2850 Link = GetFirstNode (&FormSet->FormListHead);\r
2851 while (!IsNull (&FormSet->FormListHead, Link)) {\r
2852 CurrentForm = FORM_BROWSER_FORM_FROM_LINK (Link);\r
1436aea4 2853 Link = GetNextNode (&FormSet->FormListHead, Link);\r
7c6c064c 2854\r
1436aea4 2855 UpdateFlagForForm (SetFlag, FormSet, CurrentForm);\r
7c6c064c
ED
2856 }\r
2857}\r
938baa1f 2858\r
4d4deaac 2859/**\r
d1102dba
LG
2860 Base on the return Progress string to find the form.\r
2861\r
4d4deaac
ED
2862 Base on the first return Offset/Width (Name) string to find the form\r
2863 which keep this string.\r
2864\r
2865 @param FormSet FormSet data structure.\r
2866 @param Storage Storage which has this Progress string.\r
2867 @param Progress The Progress string which has the first fail string.\r
2868 @param RetForm The return form for this progress string.\r
2869 @param RetQuestion The return question for the error progress string.\r
2870\r
2871 @retval TRUE Find the error form and statement for this error progress string.\r
2872 @retval FALSE Not find the error form.\r
2873\r
2874**/\r
2875BOOLEAN\r
2876FindQuestionFromProgress (\r
1436aea4
MK
2877 IN FORM_BROWSER_FORMSET *FormSet,\r
2878 IN BROWSER_STORAGE *Storage,\r
2879 IN EFI_STRING Progress,\r
2880 OUT FORM_BROWSER_FORM **RetForm,\r
2881 OUT FORM_BROWSER_STATEMENT **RetQuestion\r
4d4deaac
ED
2882 )\r
2883{\r
2884 LIST_ENTRY *Link;\r
2885 LIST_ENTRY *LinkStorage;\r
2886 LIST_ENTRY *LinkStatement;\r
2887 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
2888 FORM_BROWSER_FORM *Form;\r
2889 EFI_STRING EndStr;\r
2890 FORM_BROWSER_STATEMENT *Statement;\r
2891\r
2892 ASSERT ((*Progress == '&') || (*Progress == 'G'));\r
2893\r
2894 ConfigInfo = NULL;\r
2895 *RetForm = NULL;\r
2896 *RetQuestion = NULL;\r
2897\r
2898 //\r
2899 // Skip the first "&" or the ConfigHdr part.\r
2900 //\r
2901 if (*Progress == '&') {\r
2902 Progress++;\r
2903 } else {\r
2904 //\r
2905 // Prepare the "NAME" or "OFFSET=0x####&WIDTH=0x####" string.\r
2906 //\r
2907 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
2908 //\r
2909 // For Name/Value type, Skip the ConfigHdr part.\r
2910 //\r
2911 EndStr = StrStr (Progress, L"PATH=");\r
e77d2f9d 2912 ASSERT (EndStr != NULL);\r
4d4deaac
ED
2913 while (*EndStr != '&') {\r
2914 EndStr++;\r
2915 }\r
2916\r
2917 *EndStr = '\0';\r
2918 } else {\r
2919 //\r
2920 // For Buffer type, Skip the ConfigHdr part.\r
2921 //\r
2922 EndStr = StrStr (Progress, L"&OFFSET=");\r
e77d2f9d 2923 ASSERT (EndStr != NULL);\r
4d4deaac
ED
2924 *EndStr = '\0';\r
2925 }\r
2926\r
2927 Progress = EndStr + 1;\r
2928 }\r
2929\r
2930 //\r
2931 // Prepare the "NAME" or "OFFSET=0x####&WIDTH=0x####" string.\r
2932 //\r
2933 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
2934 //\r
2935 // For Name/Value type, the data is "&Fred=16&George=16&Ron=12" formset,\r
2936 // here, just keep the "Fred" string.\r
2937 //\r
2938 EndStr = StrStr (Progress, L"=");\r
e77d2f9d 2939 ASSERT (EndStr != NULL);\r
4d4deaac
ED
2940 *EndStr = '\0';\r
2941 } else {\r
2942 //\r
2943 // For Buffer type, the data is "OFFSET=0x####&WIDTH=0x####&VALUE=0x####",\r
2944 // here, just keep the "OFFSET=0x####&WIDTH=0x####" string.\r
2945 //\r
2946 EndStr = StrStr (Progress, L"&VALUE=");\r
e77d2f9d 2947 ASSERT (EndStr != NULL);\r
4d4deaac
ED
2948 *EndStr = '\0';\r
2949 }\r
2950\r
2951 //\r
2952 // Search in the form list.\r
2953 //\r
2954 Link = GetFirstNode (&FormSet->FormListHead);\r
2955 while (!IsNull (&FormSet->FormListHead, Link)) {\r
2956 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
2957 Link = GetNextNode (&FormSet->FormListHead, Link);\r
2958\r
2959 //\r
2960 // Search in the ConfigReqeust list in this form.\r
2961 //\r
2962 LinkStorage = GetFirstNode (&Form->ConfigRequestHead);\r
2963 while (!IsNull (&Form->ConfigRequestHead, LinkStorage)) {\r
1436aea4 2964 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (LinkStorage);\r
4d4deaac
ED
2965 LinkStorage = GetNextNode (&Form->ConfigRequestHead, LinkStorage);\r
2966\r
2967 if (Storage != ConfigInfo->Storage) {\r
2968 continue;\r
2969 }\r
2970\r
2971 if (StrStr (ConfigInfo->ConfigRequest, Progress) != NULL) {\r
2972 //\r
2973 // Find the OffsetWidth string in this form.\r
2974 //\r
2975 *RetForm = Form;\r
2976 break;\r
2977 }\r
2978 }\r
2979\r
2980 if (*RetForm != NULL) {\r
2981 LinkStatement = GetFirstNode (&Form->StatementListHead);\r
2982 while (!IsNull (&Form->StatementListHead, LinkStatement)) {\r
1436aea4 2983 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (LinkStatement);\r
4d4deaac
ED
2984 LinkStatement = GetNextNode (&Form->StatementListHead, LinkStatement);\r
2985\r
1436aea4 2986 if ((Statement->BlockName != NULL) && (StrStr (Statement->BlockName, Progress) != NULL)) {\r
4d4deaac
ED
2987 *RetQuestion = Statement;\r
2988 break;\r
2989 }\r
a35ecb75 2990\r
1436aea4 2991 if ((Statement->VariableName != NULL) && (StrStr (Statement->VariableName, Progress) != NULL)) {\r
a35ecb75
ED
2992 *RetQuestion = Statement;\r
2993 break;\r
2994 }\r
4d4deaac
ED
2995 }\r
2996 }\r
2997\r
2998 if (*RetForm != NULL) {\r
2999 break;\r
3000 }\r
3001 }\r
3002\r
3003 //\r
3004 // restore the OffsetWidth string to the original format.\r
3005 //\r
3006 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
3007 *EndStr = '=';\r
3008 } else {\r
3009 *EndStr = '&';\r
3010 }\r
3011\r
1436aea4 3012 return (BOOLEAN)(*RetForm != NULL);\r
4d4deaac
ED
3013}\r
3014\r
8066b27e
DB
3015/**\r
3016 Base on the return Progress string to get the SyncConfigRequest and RestoreConfigRequest\r
3017 for form and formset.\r
3018\r
3019 @param Storage Storage which has this Progress string.\r
3020 @param ConfigRequest The ConfigRequest string.\r
3021 @param Progress The Progress string which has the first fail string.\r
3022 @param RestoreConfigRequest Return the RestoreConfigRequest string.\r
3023 @param SyncConfigRequest Return the SyncConfigRequest string.\r
3024\r
3025**/\r
3026VOID\r
1436aea4
MK
3027GetSyncRestoreConfigRequest (\r
3028 IN BROWSER_STORAGE *Storage,\r
3029 IN EFI_STRING ConfigRequest,\r
3030 IN EFI_STRING Progress,\r
3031 OUT EFI_STRING *RestoreConfigRequest,\r
3032 OUT EFI_STRING *SyncConfigRequest\r
8066b27e
DB
3033 )\r
3034{\r
1436aea4
MK
3035 EFI_STRING EndStr;\r
3036 EFI_STRING ConfigHdrEndStr;\r
3037 EFI_STRING ElementStr;\r
3038 UINTN TotalSize;\r
3039 UINTN RestoreEleSize;\r
3040 UINTN SyncSize;\r
8066b27e
DB
3041\r
3042 ASSERT ((*Progress == L'&') || (*Progress == L'G'));\r
3043 //\r
3044 // If the Progress starts with ConfigHdr, means the failure is in the first name / value pair.\r
3045 // Need to restore all the fields in the ConfigRequest.\r
3046 //\r
3047 if (*Progress == L'G') {\r
3048 *RestoreConfigRequest = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);\r
3049 ASSERT (*RestoreConfigRequest != NULL);\r
3050 return;\r
3051 }\r
3052\r
3053 //\r
3054 // Find the first fail "NAME" or "OFFSET=0x####&WIDTH=0x####" string.\r
3055 //\r
3056 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
3057 //\r
3058 // For Name/Value type, the data is "&Fred=16&George=16&Ron=12" formset,\r
3059 // here, just keep the "Fred" string.\r
3060 //\r
3061 EndStr = StrStr (Progress, L"=");\r
3062 ASSERT (EndStr != NULL);\r
3063 *EndStr = L'\0';\r
3064 //\r
3065 // Find the ConfigHdr in ConfigRequest.\r
3066 //\r
3067 ConfigHdrEndStr = StrStr (ConfigRequest, L"PATH=");\r
3068 ASSERT (ConfigHdrEndStr != NULL);\r
3069 while (*ConfigHdrEndStr != L'&') {\r
3070 ConfigHdrEndStr++;\r
3071 }\r
3072 } else {\r
3073 //\r
3074 // For Buffer type, the data is "OFFSET=0x####&WIDTH=0x####&VALUE=0x####",\r
3075 // here, just keep the "OFFSET=0x####&WIDTH=0x####" string.\r
3076 //\r
3077 EndStr = StrStr (Progress, L"&VALUE=");\r
3078 ASSERT (EndStr != NULL);\r
3079 *EndStr = L'\0';\r
3080 //\r
3081 // Find the ConfigHdr in ConfigRequest.\r
3082 //\r
3083 ConfigHdrEndStr = StrStr (ConfigRequest, L"&OFFSET=");\r
3084 }\r
1436aea4 3085\r
8066b27e
DB
3086 //\r
3087 // Find the first fail pair in the ConfigRequest.\r
3088 //\r
3089 ElementStr = StrStr (ConfigRequest, Progress);\r
3090 ASSERT (ElementStr != NULL);\r
3091 //\r
3092 // To get the RestoreConfigRequest.\r
3093 //\r
1436aea4
MK
3094 RestoreEleSize = StrSize (ElementStr);\r
3095 TotalSize = (ConfigHdrEndStr - ConfigRequest) * sizeof (CHAR16) + RestoreEleSize + sizeof (CHAR16);\r
8066b27e
DB
3096 *RestoreConfigRequest = AllocateZeroPool (TotalSize);\r
3097 ASSERT (*RestoreConfigRequest != NULL);\r
3098 StrnCpyS (*RestoreConfigRequest, TotalSize / sizeof (CHAR16), ConfigRequest, ConfigHdrEndStr - ConfigRequest);\r
3099 StrCatS (*RestoreConfigRequest, TotalSize / sizeof (CHAR16), ElementStr);\r
3100 //\r
3101 // To get the SyncConfigRequest.\r
3102 //\r
1436aea4 3103 SyncSize = StrSize (ConfigRequest) - RestoreEleSize + sizeof (CHAR16);\r
8066b27e
DB
3104 *SyncConfigRequest = AllocateZeroPool (SyncSize);\r
3105 ASSERT (*SyncConfigRequest != NULL);\r
3106 StrnCpyS (*SyncConfigRequest, SyncSize / sizeof (CHAR16), ConfigRequest, SyncSize / sizeof (CHAR16) - 1);\r
3107\r
3108 //\r
3109 // restore the Progress string to the original format.\r
3110 //\r
3111 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
3112 *EndStr = L'=';\r
3113 } else {\r
3114 *EndStr = L'&';\r
3115 }\r
3116}\r
3117\r
4d4deaac
ED
3118/**\r
3119 Popup an save error info and get user input.\r
3120\r
3121 @param TitleId The form title id.\r
3122 @param HiiHandle The hii handle for this package.\r
3123\r
3124 @retval UINT32 The user select option for the save fail.\r
3125 BROWSER_ACTION_DISCARD or BROWSER_ACTION_JUMP_TO_FORMSET\r
3126**/\r
3127UINT32\r
3128ConfirmSaveFail (\r
1436aea4
MK
3129 IN EFI_STRING_ID TitleId,\r
3130 IN EFI_HII_HANDLE HiiHandle\r
4d4deaac
ED
3131 )\r
3132{\r
1436aea4
MK
3133 CHAR16 *FormTitle;\r
3134 CHAR16 *StringBuffer;\r
3135 UINT32 RetVal;\r
4d4deaac
ED
3136\r
3137 FormTitle = GetToken (TitleId, HiiHandle);\r
3138\r
3139 StringBuffer = AllocateZeroPool (256 * sizeof (CHAR16));\r
3140 ASSERT (StringBuffer != NULL);\r
3141\r
3142 UnicodeSPrint (\r
d1102dba
LG
3143 StringBuffer,\r
3144 24 * sizeof (CHAR16) + StrSize (FormTitle),\r
3145 L"Submit Fail For Form: %s.",\r
4d4deaac
ED
3146 FormTitle\r
3147 );\r
3148\r
1436aea4 3149 RetVal = PopupErrorMessage (BROWSER_SUBMIT_FAIL, NULL, NULL, StringBuffer);\r
4d4deaac
ED
3150\r
3151 FreePool (StringBuffer);\r
3152 FreePool (FormTitle);\r
3153\r
3154 return RetVal;\r
3155}\r
3156\r
3157/**\r
3158 Popup an NO_SUBMIT_IF error info and get user input.\r
3159\r
3160 @param TitleId The form title id.\r
3161 @param HiiHandle The hii handle for this package.\r
3162\r
3163 @retval UINT32 The user select option for the save fail.\r
3164 BROWSER_ACTION_DISCARD or BROWSER_ACTION_JUMP_TO_FORMSET\r
3165**/\r
3166UINT32\r
3167ConfirmNoSubmitFail (\r
1436aea4
MK
3168 IN EFI_STRING_ID TitleId,\r
3169 IN EFI_HII_HANDLE HiiHandle\r
4d4deaac
ED
3170 )\r
3171{\r
1436aea4
MK
3172 CHAR16 *FormTitle;\r
3173 CHAR16 *StringBuffer;\r
3174 UINT32 RetVal;\r
4d4deaac
ED
3175\r
3176 FormTitle = GetToken (TitleId, HiiHandle);\r
3177\r
3178 StringBuffer = AllocateZeroPool (256 * sizeof (CHAR16));\r
3179 ASSERT (StringBuffer != NULL);\r
3180\r
3181 UnicodeSPrint (\r
d1102dba
LG
3182 StringBuffer,\r
3183 24 * sizeof (CHAR16) + StrSize (FormTitle),\r
3184 L"NO_SUBMIT_IF error For Form: %s.",\r
4d4deaac
ED
3185 FormTitle\r
3186 );\r
3187\r
1436aea4 3188 RetVal = PopupErrorMessage (BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF, NULL, NULL, StringBuffer);\r
4d4deaac
ED
3189\r
3190 FreePool (StringBuffer);\r
3191 FreePool (FormTitle);\r
3192\r
3193 return RetVal;\r
3194}\r
3195\r
b18e7050 3196/**\r
48a9d5f7 3197 Discard data based on the input setting scope (Form, FormSet or System).\r
7936fb6a 3198\r
3199 @param FormSet FormSet data structure.\r
3200 @param Form Form data structure.\r
48a9d5f7 3201 @param SettingScope Setting Scope for Discard action.\r
b18e7050
ED
3202\r
3203 @retval EFI_SUCCESS The function completed successfully.\r
48a9d5f7 3204 @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
b18e7050
ED
3205\r
3206**/\r
3207EFI_STATUS\r
3208DiscardForm (\r
1436aea4
MK
3209 IN FORM_BROWSER_FORMSET *FormSet,\r
3210 IN FORM_BROWSER_FORM *Form,\r
3211 IN BROWSER_SETTING_SCOPE SettingScope\r
b18e7050
ED
3212 )\r
3213{\r
48a9d5f7
LG
3214 LIST_ENTRY *Link;\r
3215 FORMSET_STORAGE *Storage;\r
b18e7050 3216 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
6e74560f
ED
3217 FORM_BROWSER_FORMSET *LocalFormSet;\r
3218 FORM_BROWSER_FORMSET *OldFormSet;\r
b18e7050 3219\r
48a9d5f7
LG
3220 //\r
3221 // Check the supported setting level.\r
3222 //\r
3223 if (SettingScope >= MaxLevel) {\r
3224 return EFI_UNSUPPORTED;\r
3225 }\r
b18e7050 3226\r
1436aea4 3227 if ((SettingScope == FormLevel) && IsNvUpdateRequiredForForm (Form)) {\r
48a9d5f7 3228 ConfigInfo = NULL;\r
1436aea4 3229 Link = GetFirstNode (&Form->ConfigRequestHead);\r
48a9d5f7
LG
3230 while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
3231 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
1436aea4 3232 Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
b18e7050 3233\r
48a9d5f7
LG
3234 if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
3235 continue;\r
3236 }\r
3237\r
3238 //\r
3239 // Skip if there is no RequestElement\r
3240 //\r
3241 if (ConfigInfo->ElementCount == 0) {\r
3242 continue;\r
b18e7050
ED
3243 }\r
3244\r
48a9d5f7
LG
3245 //\r
3246 // Prepare <ConfigResp>\r
3247 //\r
1436aea4 3248 SynchronizeStorage (ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);\r
816a7110 3249\r
816a7110
ED
3250 //\r
3251 // Call callback with Changed type to inform the driver.\r
3252 //\r
3253 SendDiscardInfoToDriver (FormSet, Form);\r
3254 }\r
3255\r
4d4deaac 3256 ValueChangeResetFlagUpdate (FALSE, FormSet, Form);\r
1436aea4 3257 } else if ((SettingScope == FormSetLevel) && IsNvUpdateRequiredForFormSet (FormSet)) {\r
48a9d5f7
LG
3258 //\r
3259 // Discard Buffer storage or Name/Value storage\r
3260 //\r
3261 Link = GetFirstNode (&FormSet->StorageListHead);\r
3262 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
3263 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
1436aea4 3264 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
48a9d5f7 3265\r
94f3aae7 3266 if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
48a9d5f7
LG
3267 continue;\r
3268 }\r
3269\r
b18e7050 3270 //\r
48a9d5f7 3271 // Skip if there is no RequestElement\r
b18e7050 3272 //\r
48a9d5f7
LG
3273 if (Storage->ElementCount == 0) {\r
3274 continue;\r
3275 }\r
b18e7050 3276\r
1436aea4 3277 SynchronizeStorage (Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
48a9d5f7 3278 }\r
f1660263
ED
3279\r
3280 Link = GetFirstNode (&FormSet->FormListHead);\r
3281 while (!IsNull (&FormSet->FormListHead, Link)) {\r
3282 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
3283 Link = GetNextNode (&FormSet->FormListHead, Link);\r
d1102dba 3284\r
f1660263
ED
3285 //\r
3286 // Call callback with Changed type to inform the driver.\r
3287 //\r
3288 SendDiscardInfoToDriver (FormSet, Form);\r
3289 }\r
b18e7050 3290\r
1436aea4 3291 ValueChangeResetFlagUpdate (FALSE, FormSet, NULL);\r
48a9d5f7
LG
3292 } else if (SettingScope == SystemLevel) {\r
3293 //\r
3294 // System Level Discard.\r
3295 //\r
6e74560f
ED
3296 OldFormSet = mSystemLevelFormSet;\r
3297\r
48a9d5f7
LG
3298 //\r
3299 // Discard changed value for each FormSet in the maintain list.\r
3300 //\r
3301 Link = GetFirstNode (&gBrowserFormSetList);\r
3302 while (!IsNull (&gBrowserFormSetList, Link)) {\r
3303 LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
1436aea4
MK
3304 Link = GetNextNode (&gBrowserFormSetList, Link);\r
3305 if (!ValidateFormSet (LocalFormSet)) {\r
938baa1f
ED
3306 continue;\r
3307 }\r
6e74560f
ED
3308\r
3309 mSystemLevelFormSet = LocalFormSet;\r
3310\r
938baa1f 3311 DiscardForm (LocalFormSet, NULL, FormSetLevel);\r
48a9d5f7 3312 if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
b18e7050 3313 //\r
48a9d5f7 3314 // Remove maintain backup list after discard except for the current using FormSet.\r
b18e7050 3315 //\r
1436aea4 3316 CleanBrowserStorage (LocalFormSet);\r
48a9d5f7
LG
3317 RemoveEntryList (&LocalFormSet->Link);\r
3318 DestroyFormSet (LocalFormSet);\r
b18e7050 3319 }\r
b18e7050 3320 }\r
6e74560f
ED
3321\r
3322 mSystemLevelFormSet = OldFormSet;\r
b18e7050
ED
3323 }\r
3324\r
d1102dba 3325 return EFI_SUCCESS;\r
b18e7050
ED
3326}\r
3327\r
3328/**\r
4d4deaac 3329 Submit data for a form.\r
b18e7050
ED
3330\r
3331 @param FormSet FormSet data structure.\r
3332 @param Form Form data structure.\r
7936fb6a 3333\r
3334 @retval EFI_SUCCESS The function completed successfully.\r
48a9d5f7 3335 @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
7936fb6a 3336\r
3337**/\r
3338EFI_STATUS\r
4d4deaac 3339SubmitForForm (\r
1436aea4
MK
3340 IN FORM_BROWSER_FORMSET *FormSet,\r
3341 IN FORM_BROWSER_FORM *Form\r
7936fb6a 3342 )\r
3343{\r
1436aea4
MK
3344 EFI_STATUS Status;\r
3345 LIST_ENTRY *Link;\r
3346 EFI_STRING ConfigResp;\r
3347 EFI_STRING Progress;\r
3348 BROWSER_STORAGE *Storage;\r
b18e7050 3349 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
1436aea4 3350 BOOLEAN SubmitFormFail;\r
fdd530d6
DB
3351\r
3352 SubmitFormFail = FALSE;\r
7936fb6a 3353\r
4d4deaac
ED
3354 if (!IsNvUpdateRequiredForForm (Form)) {\r
3355 return EFI_SUCCESS;\r
3356 }\r
3357\r
3358 Status = NoSubmitCheck (FormSet, &Form, NULL);\r
3359 if (EFI_ERROR (Status)) {\r
3360 return Status;\r
3361 }\r
3362\r
3363 Link = GetFirstNode (&Form->ConfigRequestHead);\r
3364 while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
3365 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
1436aea4 3366 Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
4d4deaac
ED
3367\r
3368 Storage = ConfigInfo->Storage;\r
3369 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
3370 continue;\r
3371 }\r
3372\r
3373 //\r
3374 // Skip if there is no RequestElement\r
3375 //\r
3376 if (ConfigInfo->ElementCount == 0) {\r
3377 continue;\r
3378 }\r
3379\r
3380 //\r
3381 // 1. Prepare <ConfigResp>\r
3382 //\r
3383 Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest, TRUE);\r
3384 if (EFI_ERROR (Status)) {\r
3385 return Status;\r
3386 }\r
3387\r
3388 //\r
3389 // 2. Set value to hii config routine protocol.\r
3390 //\r
3391 Status = mHiiConfigRouting->RouteConfig (\r
1436aea4
MK
3392 mHiiConfigRouting,\r
3393 ConfigResp,\r
3394 &Progress\r
3395 );\r
4d4deaac
ED
3396\r
3397 if (EFI_ERROR (Status)) {\r
8066b27e
DB
3398 //\r
3399 // Submit fail, to get the RestoreConfigRequest and SyncConfigRequest.\r
3400 //\r
fdd530d6 3401 SubmitFormFail = TRUE;\r
8066b27e 3402 GetSyncRestoreConfigRequest (ConfigInfo->Storage, ConfigInfo->ConfigRequest, Progress, &ConfigInfo->RestoreConfigRequest, &ConfigInfo->SyncConfigRequest);\r
4d4deaac 3403 InsertTailList (&gBrowserSaveFailFormSetList, &ConfigInfo->SaveFailLink);\r
fa209e8c 3404 FreePool (ConfigResp);\r
4d4deaac
ED
3405 continue;\r
3406 }\r
3407\r
fa209e8c 3408 FreePool (ConfigResp);\r
4d4deaac
ED
3409 //\r
3410 // 3. Config success, update storage shadow Buffer, only update the data belong to this form.\r
3411 //\r
3412 SynchronizeStorage (ConfigInfo->Storage, ConfigInfo->ConfigRequest, TRUE);\r
3413 }\r
3414\r
48a9d5f7 3415 //\r
4d4deaac 3416 // 4. Process the save failed storage.\r
48a9d5f7 3417 //\r
4d4deaac
ED
3418 if (!IsListEmpty (&gBrowserSaveFailFormSetList)) {\r
3419 if (ConfirmSaveFail (Form->FormTitle, FormSet->HiiHandle) == BROWSER_ACTION_DISCARD) {\r
3420 Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
3421 while (!IsNull (&gBrowserSaveFailFormSetList, Link)) {\r
3422 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_SAVE_FAIL_LINK (Link);\r
1436aea4 3423 Link = GetNextNode (&gBrowserSaveFailFormSetList, Link);\r
8066b27e
DB
3424 //\r
3425 // Process the submit fail question, base on the RestoreConfigRequest to restore the EditBuffer\r
3426 // base on the SyncConfigRequest to Sync the buffer.\r
3427 //\r
3428 SynchronizeStorage (ConfigInfo->Storage, ConfigInfo->RestoreConfigRequest, FALSE);\r
3429 FreePool (ConfigInfo->RestoreConfigRequest);\r
3430 ConfigInfo->RestoreConfigRequest = NULL;\r
3431 if (ConfigInfo->SyncConfigRequest != NULL) {\r
1436aea4 3432 SynchronizeStorage (ConfigInfo->Storage, ConfigInfo->SyncConfigRequest, TRUE);\r
8066b27e
DB
3433 FreePool (ConfigInfo->SyncConfigRequest);\r
3434 ConfigInfo->SyncConfigRequest = NULL;\r
3435 }\r
4d4deaac
ED
3436\r
3437 Status = EFI_SUCCESS;\r
3438 }\r
1436aea4
MK
3439\r
3440 SendDiscardInfoToDriver (FormSet, Form);\r
4d4deaac
ED
3441 } else {\r
3442 Status = EFI_UNSUPPORTED;\r
3443 }\r
3444\r
3445 //\r
3446 // Free Form save fail list.\r
3447 //\r
3448 while (!IsListEmpty (&gBrowserSaveFailFormSetList)) {\r
1436aea4 3449 Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
4d4deaac
ED
3450 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_SAVE_FAIL_LINK (Link);\r
3451 RemoveEntryList (&ConfigInfo->SaveFailLink);\r
3452 }\r
48a9d5f7
LG
3453 }\r
3454\r
7936fb6a 3455 //\r
4d4deaac 3456 // 5. Update the NV flag.\r
7936fb6a 3457 //\r
1436aea4 3458 ValueChangeResetFlagUpdate (TRUE, FormSet, Form);\r
4d4deaac 3459\r
3cb44c20
DB
3460 //\r
3461 // 6 Call callback with Submitted type to inform the driver.\r
3462 //\r
fdd530d6
DB
3463 if (!SubmitFormFail) {\r
3464 SubmitCallback (FormSet, Form);\r
3465 }\r
3cb44c20 3466\r
4d4deaac
ED
3467 return Status;\r
3468}\r
3469\r
3470/**\r
3471 Submit data for a formset.\r
3472\r
3473 @param FormSet FormSet data structure.\r
3474 @param SkipProcessFail Whether skip to process the save failed storage.\r
d1102dba
LG
3475 If submit formset is called when do system level save,\r
3476 set this value to true and process the failed formset\r
3477 together.\r
4d4deaac
ED
3478 if submit formset is called when do formset level save,\r
3479 set the value to false and process the failed storage\r
3480 right after process all storages for this formset.\r
3481\r
3482 @retval EFI_SUCCESS The function completed successfully.\r
3483 @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
3484\r
3485**/\r
3486EFI_STATUS\r
3487SubmitForFormSet (\r
1436aea4
MK
3488 IN FORM_BROWSER_FORMSET *FormSet,\r
3489 IN BOOLEAN SkipProcessFail\r
4d4deaac
ED
3490 )\r
3491{\r
3492 EFI_STATUS Status;\r
3493 LIST_ENTRY *Link;\r
3494 EFI_STRING ConfigResp;\r
3495 EFI_STRING Progress;\r
3496 BROWSER_STORAGE *Storage;\r
3497 FORMSET_STORAGE *FormSetStorage;\r
3498 FORM_BROWSER_FORM *Form;\r
3499 BOOLEAN HasInserted;\r
3500 FORM_BROWSER_STATEMENT *Question;\r
fdd530d6 3501 BOOLEAN SubmitFormSetFail;\r
b6f07bdd 3502 BOOLEAN DiscardChange;\r
4d4deaac 3503\r
1436aea4 3504 HasInserted = FALSE;\r
fdd530d6 3505 SubmitFormSetFail = FALSE;\r
b6f07bdd 3506 DiscardChange = FALSE;\r
4d4deaac
ED
3507\r
3508 if (!IsNvUpdateRequiredForFormSet (FormSet)) {\r
3509 return EFI_SUCCESS;\r
b18e7050 3510 }\r
4d4deaac 3511\r
1436aea4 3512 Form = NULL;\r
4d4deaac 3513 Status = NoSubmitCheck (FormSet, &Form, &Question);\r
7936fb6a 3514 if (EFI_ERROR (Status)) {\r
4d4deaac
ED
3515 if (SkipProcessFail) {\r
3516 //\r
3517 // Process NO_SUBMIT check first, so insert it at head.\r
3518 //\r
1436aea4 3519 FormSet->SaveFailForm = Form;\r
4d4deaac
ED
3520 FormSet->SaveFailStatement = Question;\r
3521 InsertHeadList (&gBrowserSaveFailFormSetList, &FormSet->SaveFailLink);\r
3522 }\r
3523\r
7936fb6a 3524 return Status;\r
3525 }\r
3526\r
1436aea4 3527 Form = NULL;\r
4d4deaac
ED
3528 Question = NULL;\r
3529 //\r
3530 // Submit Buffer storage or Name/Value storage\r
3531 //\r
3532 Link = GetFirstNode (&FormSet->StorageListHead);\r
3533 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
3534 FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
3535 Storage = FormSetStorage->BrowserStorage;\r
1436aea4 3536 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
7936fb6a 3537\r
4d4deaac
ED
3538 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
3539 continue;\r
3540 }\r
7936fb6a 3541\r
4d4deaac
ED
3542 //\r
3543 // Skip if there is no RequestElement\r
3544 //\r
3545 if (FormSetStorage->ElementCount == 0) {\r
3546 continue;\r
3547 }\r
7936fb6a 3548\r
4d4deaac
ED
3549 //\r
3550 // 1. Prepare <ConfigResp>\r
3551 //\r
3552 Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest, TRUE);\r
3553 if (EFI_ERROR (Status)) {\r
3554 return Status;\r
3555 }\r
b18e7050 3556\r
4d4deaac
ED
3557 //\r
3558 // 2. Send <ConfigResp> to Routine config Protocol.\r
3559 //\r
3560 Status = mHiiConfigRouting->RouteConfig (\r
1436aea4
MK
3561 mHiiConfigRouting,\r
3562 ConfigResp,\r
3563 &Progress\r
3564 );\r
4d4deaac 3565 if (EFI_ERROR (Status)) {\r
8066b27e
DB
3566 //\r
3567 // Submit fail, to get the RestoreConfigRequest and SyncConfigRequest.\r
3568 //\r
fdd530d6 3569 SubmitFormSetFail = TRUE;\r
8066b27e 3570 GetSyncRestoreConfigRequest (FormSetStorage->BrowserStorage, FormSetStorage->ConfigRequest, Progress, &FormSetStorage->RestoreConfigRequest, &FormSetStorage->SyncConfigRequest);\r
4d4deaac
ED
3571 InsertTailList (&FormSet->SaveFailStorageListHead, &FormSetStorage->SaveFailLink);\r
3572 if (!HasInserted) {\r
3573 //\r
3574 // Call submit formset for system level, save the formset info\r
3575 // and process later.\r
3576 //\r
1436aea4 3577 FindQuestionFromProgress (FormSet, Storage, Progress, &Form, &Question);\r
4d4deaac 3578 ASSERT (Form != NULL && Question != NULL);\r
1436aea4 3579 FormSet->SaveFailForm = Form;\r
4d4deaac
ED
3580 FormSet->SaveFailStatement = Question;\r
3581 if (SkipProcessFail) {\r
3582 InsertTailList (&gBrowserSaveFailFormSetList, &FormSet->SaveFailLink);\r
3583 }\r
1436aea4 3584\r
4d4deaac 3585 HasInserted = TRUE;\r
b18e7050 3586 }\r
7248790e 3587\r
b18e7050 3588 FreePool (ConfigResp);\r
4d4deaac 3589 continue;\r
7936fb6a 3590 }\r
3591\r
4d4deaac 3592 FreePool (ConfigResp);\r
cce6230f 3593 //\r
4d4deaac 3594 // 3. Config success, update storage shadow Buffer\r
7936fb6a 3595 //\r
4d4deaac
ED
3596 SynchronizeStorage (Storage, FormSetStorage->ConfigRequest, TRUE);\r
3597 }\r
b18e7050 3598\r
4d4deaac
ED
3599 //\r
3600 // 4. Has save fail storage need to handle.\r
3601 //\r
3602 if (Form != NULL) {\r
3603 if (!SkipProcessFail) {\r
b18e7050 3604 //\r
4d4deaac 3605 // If not in system level, just handl the save failed storage here.\r
b18e7050 3606 //\r
4d4deaac 3607 if (ConfirmSaveFail (Form->FormTitle, FormSet->HiiHandle) == BROWSER_ACTION_DISCARD) {\r
b6f07bdd 3608 DiscardChange = TRUE;\r
1436aea4 3609 Link = GetFirstNode (&FormSet->SaveFailStorageListHead);\r
4d4deaac
ED
3610 while (!IsNull (&FormSet->SaveFailStorageListHead, Link)) {\r
3611 FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (Link);\r
3612 Storage = FormSetStorage->BrowserStorage;\r
1436aea4 3613 Link = GetNextNode (&FormSet->SaveFailStorageListHead, Link);\r
8066b27e
DB
3614 //\r
3615 // Process the submit fail question, base on the RestoreConfigRequest to restore the EditBuffer\r
3616 // base on the SyncConfigRequest to Sync the buffer.\r
3617 //\r
3618 SynchronizeStorage (FormSetStorage->BrowserStorage, FormSetStorage->RestoreConfigRequest, FALSE);\r
3619 FreePool (FormSetStorage->RestoreConfigRequest);\r
3620 FormSetStorage->RestoreConfigRequest = NULL;\r
3621 if (FormSetStorage->SyncConfigRequest != NULL) {\r
1436aea4 3622 SynchronizeStorage (FormSetStorage->BrowserStorage, FormSetStorage->SyncConfigRequest, TRUE);\r
8066b27e
DB
3623 FreePool (FormSetStorage->SyncConfigRequest);\r
3624 FormSetStorage->SyncConfigRequest = NULL;\r
3625 }\r
4d4deaac
ED
3626\r
3627 Status = EFI_SUCCESS;\r
3628 }\r
3629 } else {\r
1436aea4 3630 UiCopyMenuList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &Form->FormViewListHead);\r
4d4deaac
ED
3631\r
3632 gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
3633 gCurrentSelection->Handle = FormSet->HiiHandle;\r
3634 CopyGuid (&gCurrentSelection->FormSetGuid, &FormSet->Guid);\r
1436aea4 3635 gCurrentSelection->FormId = Form->FormId;\r
4d4deaac
ED
3636 gCurrentSelection->QuestionId = Question->QuestionId;\r
3637\r
3638 Status = EFI_UNSUPPORTED;\r
7936fb6a 3639 }\r
b18e7050 3640\r
7248790e 3641 //\r
4d4deaac 3642 // Free FormSet save fail list.\r
7248790e 3643 //\r
4d4deaac 3644 while (!IsListEmpty (&FormSet->SaveFailStorageListHead)) {\r
1436aea4 3645 Link = GetFirstNode (&FormSet->SaveFailStorageListHead);\r
4d4deaac
ED
3646 FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (Link);\r
3647 RemoveEntryList (&FormSetStorage->SaveFailLink);\r
b18e7050 3648 }\r
4d4deaac 3649 } else {\r
b18e7050 3650 //\r
4d4deaac 3651 // If in system level, just return error and handle the failed formset later.\r
b18e7050 3652 //\r
4d4deaac
ED
3653 Status = EFI_UNSUPPORTED;\r
3654 }\r
3655 }\r
3656\r
b6f07bdd
DB
3657 //\r
3658 // If user discard the change, send the discard info to driver.\r
3659 //\r
3660 if (DiscardChange) {\r
3661 Link = GetFirstNode (&FormSet->FormListHead);\r
3662 while (!IsNull (&FormSet->FormListHead, Link)) {\r
3663 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
3664 Link = GetNextNode (&FormSet->FormListHead, Link);\r
3665 //\r
3666 // Call callback with Changed type to inform the driver.\r
3667 //\r
3668 SendDiscardInfoToDriver (FormSet, Form);\r
3669 }\r
3670 }\r
3671\r
4d4deaac
ED
3672 //\r
3673 // 5. Update the NV flag.\r
d1102dba 3674 //\r
1436aea4 3675 ValueChangeResetFlagUpdate (TRUE, FormSet, NULL);\r
4d4deaac 3676\r
3cb44c20
DB
3677 //\r
3678 // 6. Call callback with Submitted type to inform the driver.\r
3679 //\r
fdd530d6
DB
3680 if (!SubmitFormSetFail) {\r
3681 SubmitCallback (FormSet, NULL);\r
3682 }\r
3cb44c20 3683\r
4d4deaac
ED
3684 return Status;\r
3685}\r
3686\r
3687/**\r
3688 Submit data for all formsets.\r
3689\r
3690 @retval EFI_SUCCESS The function completed successfully.\r
3691 @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
3692\r
3693**/\r
3694EFI_STATUS\r
3695SubmitForSystem (\r
3696 VOID\r
3697 )\r
3698{\r
3699 EFI_STATUS Status;\r
3700 LIST_ENTRY *Link;\r
91927805 3701 LIST_ENTRY *FormLink;\r
4d4deaac 3702 LIST_ENTRY *StorageLink;\r
4d4deaac
ED
3703 FORMSET_STORAGE *FormSetStorage;\r
3704 FORM_BROWSER_FORM *Form;\r
3705 FORM_BROWSER_FORMSET *LocalFormSet;\r
3706 UINT32 UserSelection;\r
3707 FORM_BROWSER_STATEMENT *Question;\r
3708\r
3709 mSystemSubmit = TRUE;\r
1436aea4 3710 Link = GetFirstNode (&gBrowserFormSetList);\r
4d4deaac
ED
3711 while (!IsNull (&gBrowserFormSetList, Link)) {\r
3712 LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
1436aea4
MK
3713 Link = GetNextNode (&gBrowserFormSetList, Link);\r
3714 if (!ValidateFormSet (LocalFormSet)) {\r
4d4deaac
ED
3715 continue;\r
3716 }\r
3717\r
3718 Status = SubmitForFormSet (LocalFormSet, TRUE);\r
3719 if (EFI_ERROR (Status)) {\r
3720 continue;\r
7936fb6a 3721 }\r
7936fb6a 3722\r
cce6230f 3723 //\r
4d4deaac 3724 // Remove maintain backup list after save except for the current using FormSet.\r
d1102dba 3725 //\r
4d4deaac 3726 if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
1436aea4 3727 CleanBrowserStorage (LocalFormSet);\r
4d4deaac
ED
3728 RemoveEntryList (&LocalFormSet->Link);\r
3729 DestroyFormSet (LocalFormSet);\r
3730 }\r
3731 }\r
1436aea4 3732\r
4d4deaac
ED
3733 mSystemSubmit = FALSE;\r
3734\r
3735 Status = EFI_SUCCESS;\r
3736\r
3737 //\r
3738 // Process the save failed formsets.\r
3739 //\r
3740 Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
3741 while (!IsNull (&gBrowserSaveFailFormSetList, Link)) {\r
3742 LocalFormSet = FORM_BROWSER_FORMSET_FROM_SAVE_FAIL_LINK (Link);\r
1436aea4 3743 Link = GetNextNode (&gBrowserSaveFailFormSetList, Link);\r
4d4deaac 3744\r
1436aea4 3745 if (!ValidateFormSet (LocalFormSet)) {\r
4d4deaac
ED
3746 continue;\r
3747 }\r
3748\r
1436aea4
MK
3749 Form = LocalFormSet->SaveFailForm;\r
3750 Question = LocalFormSet->SaveFailStatement;\r
48a9d5f7
LG
3751\r
3752 //\r
4d4deaac 3753 // Confirm with user, get user input.\r
48a9d5f7 3754 //\r
4d4deaac
ED
3755 if (IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
3756 //\r
3757 // NULL for SaveFailStorageListHead means error caused by NO_SUBMIT_IF check.\r
3758 //\r
3759 UserSelection = ConfirmNoSubmitFail (Form->FormTitle, LocalFormSet->HiiHandle);\r
3760 } else {\r
3761 UserSelection = ConfirmSaveFail (Form->FormTitle, LocalFormSet->HiiHandle);\r
3762 }\r
3763\r
3764 if (UserSelection == BROWSER_ACTION_DISCARD) {\r
3765 if (IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
3766 StorageLink = GetFirstNode (&LocalFormSet->StorageListHead);\r
3767 while (!IsNull (&LocalFormSet->StorageListHead, StorageLink)) {\r
3768 FormSetStorage = FORMSET_STORAGE_FROM_LINK (StorageLink);\r
1436aea4 3769 StorageLink = GetNextNode (&LocalFormSet->StorageListHead, StorageLink);\r
4d4deaac 3770\r
1436aea4 3771 SynchronizeStorage (FormSetStorage->BrowserStorage, FormSetStorage->ConfigRequest, FALSE);\r
4d4deaac
ED
3772 }\r
3773 } else {\r
3774 StorageLink = GetFirstNode (&LocalFormSet->SaveFailStorageListHead);\r
3775 while (!IsNull (&LocalFormSet->SaveFailStorageListHead, StorageLink)) {\r
3776 FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (StorageLink);\r
1436aea4 3777 StorageLink = GetNextNode (&LocalFormSet->SaveFailStorageListHead, StorageLink);\r
8066b27e
DB
3778 //\r
3779 // Process the submit fail question, base on the RestoreConfigRequest to restore the EditBuffer\r
3780 // base on the SyncConfigRequest to Sync the buffer.\r
3781 //\r
3782 SynchronizeStorage (FormSetStorage->BrowserStorage, FormSetStorage->RestoreConfigRequest, FALSE);\r
3783 FreePool (FormSetStorage->RestoreConfigRequest);\r
3784 FormSetStorage->RestoreConfigRequest = NULL;\r
3785 if ( FormSetStorage->SyncConfigRequest != NULL) {\r
3786 SynchronizeStorage (FormSetStorage->BrowserStorage, FormSetStorage->SyncConfigRequest, TRUE);\r
3787 FreePool (FormSetStorage->SyncConfigRequest);\r
3788 FormSetStorage->SyncConfigRequest = NULL;\r
3789 }\r
4d4deaac 3790 }\r
938baa1f 3791 }\r
4d4deaac 3792\r
91927805
DB
3793 FormLink = GetFirstNode (&LocalFormSet->FormListHead);\r
3794 while (!IsNull (&LocalFormSet->FormListHead, FormLink)) {\r
1436aea4 3795 Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
91927805 3796 FormLink = GetNextNode (&LocalFormSet->FormListHead, FormLink);\r
b6f07bdd
DB
3797 //\r
3798 // Call callback with Changed type to inform the driver.\r
3799 //\r
3800 SendDiscardInfoToDriver (LocalFormSet, Form);\r
3801 }\r
3802\r
48a9d5f7 3803 if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
1436aea4 3804 CleanBrowserStorage (LocalFormSet);\r
48a9d5f7 3805 RemoveEntryList (&LocalFormSet->Link);\r
4d4deaac 3806 RemoveEntryList (&LocalFormSet->SaveFailLink);\r
48a9d5f7 3807 DestroyFormSet (LocalFormSet);\r
4d4deaac 3808 } else {\r
1436aea4 3809 ValueChangeResetFlagUpdate (FALSE, LocalFormSet, NULL);\r
48a9d5f7 3810 }\r
4d4deaac
ED
3811 } else {\r
3812 if (IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
3813 NoSubmitCheck (LocalFormSet, &Form, &Question);\r
3814 }\r
3815\r
1436aea4 3816 UiCopyMenuList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &Form->FormViewListHead);\r
4d4deaac
ED
3817\r
3818 gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
3819 gCurrentSelection->Handle = LocalFormSet->HiiHandle;\r
3820 CopyGuid (&gCurrentSelection->FormSetGuid, &LocalFormSet->Guid);\r
1436aea4 3821 gCurrentSelection->FormId = Form->FormId;\r
4d4deaac
ED
3822 gCurrentSelection->QuestionId = Question->QuestionId;\r
3823\r
3824 Status = EFI_UNSUPPORTED;\r
3825 break;\r
48a9d5f7 3826 }\r
7936fb6a 3827 }\r
3828\r
4d4deaac
ED
3829 //\r
3830 // Clean the list which will not process.\r
3831 //\r
3832 while (!IsListEmpty (&gBrowserSaveFailFormSetList)) {\r
1436aea4 3833 Link = GetFirstNode (&gBrowserSaveFailFormSetList);\r
4d4deaac
ED
3834 LocalFormSet = FORM_BROWSER_FORMSET_FROM_SAVE_FAIL_LINK (Link);\r
3835 RemoveEntryList (&LocalFormSet->SaveFailLink);\r
3836\r
3837 while (!IsListEmpty (&LocalFormSet->SaveFailStorageListHead)) {\r
1436aea4 3838 StorageLink = GetFirstNode (&LocalFormSet->SaveFailStorageListHead);\r
4d4deaac
ED
3839 FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (StorageLink);\r
3840 RemoveEntryList (&FormSetStorage->SaveFailLink);\r
3841 }\r
3842 }\r
3843\r
3844 return Status;\r
3845}\r
3846\r
3847/**\r
3848 Submit data based on the input Setting level (Form, FormSet or System).\r
3849\r
3850 @param FormSet FormSet data structure.\r
3851 @param Form Form data structure.\r
3852 @param SettingScope Setting Scope for Submit action.\r
3853\r
3854 @retval EFI_SUCCESS The function completed successfully.\r
3855 @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
3856\r
3857**/\r
3858EFI_STATUS\r
3859SubmitForm (\r
1436aea4
MK
3860 IN FORM_BROWSER_FORMSET *FormSet,\r
3861 IN FORM_BROWSER_FORM *Form,\r
3862 IN BROWSER_SETTING_SCOPE SettingScope\r
4d4deaac
ED
3863 )\r
3864{\r
1436aea4 3865 EFI_STATUS Status;\r
4d4deaac
ED
3866\r
3867 switch (SettingScope) {\r
1436aea4
MK
3868 case FormLevel:\r
3869 Status = SubmitForForm (FormSet, Form);\r
3870 break;\r
4d4deaac 3871\r
1436aea4
MK
3872 case FormSetLevel:\r
3873 Status = SubmitForFormSet (FormSet, FALSE);\r
3874 break;\r
4d4deaac 3875\r
1436aea4
MK
3876 case SystemLevel:\r
3877 Status = SubmitForSystem ();\r
3878 break;\r
4d4deaac 3879\r
1436aea4
MK
3880 default:\r
3881 Status = EFI_UNSUPPORTED;\r
3882 break;\r
4d4deaac
ED
3883 }\r
3884\r
3885 return Status;\r
7936fb6a 3886}\r
3887\r
ee31d1be 3888/**\r
7a9612ce
ED
3889 Converts the unicode character of the string from uppercase to lowercase.\r
3890 This is a internal function.\r
ee31d1be 3891\r
7a9612ce 3892 @param ConfigString String to be converted\r
ee31d1be
ED
3893\r
3894**/\r
7a9612ce
ED
3895VOID\r
3896EFIAPI\r
3897HiiToLower (\r
3898 IN EFI_STRING ConfigString\r
ee31d1be
ED
3899 )\r
3900{\r
7a9612ce
ED
3901 EFI_STRING String;\r
3902 BOOLEAN Lower;\r
ee31d1be 3903\r
7a9612ce 3904 ASSERT (ConfigString != NULL);\r
ee31d1be
ED
3905\r
3906 //\r
7a9612ce 3907 // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
ee31d1be 3908 //\r
7a9612ce
ED
3909 for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {\r
3910 if (*String == L'=') {\r
3911 Lower = TRUE;\r
3912 } else if (*String == L'&') {\r
3913 Lower = FALSE;\r
1436aea4
MK
3914 } else if (Lower && (*String >= L'A') && (*String <= L'F')) {\r
3915 *String = (CHAR16)(*String - L'A' + L'a');\r
7a9612ce 3916 }\r
ee31d1be 3917 }\r
7a9612ce 3918}\r
ee31d1be 3919\r
7a9612ce
ED
3920/**\r
3921 Find the point in the ConfigResp string for this question.\r
3922\r
3923 @param Question The question.\r
3924 @param ConfigResp Get ConfigResp string.\r
3925\r
3926 @retval point to the offset where is for this question.\r
3927\r
3928**/\r
3929CHAR16 *\r
3930GetOffsetFromConfigResp (\r
1436aea4
MK
3931 IN FORM_BROWSER_STATEMENT *Question,\r
3932 IN CHAR16 *ConfigResp\r
7a9612ce
ED
3933 )\r
3934{\r
1436aea4
MK
3935 CHAR16 *RequestElement;\r
3936 CHAR16 *BlockData;\r
ee31d1be
ED
3937\r
3938 //\r
7a9612ce 3939 // Type is EFI_HII_VARSTORE_NAME_VALUE.\r
ee31d1be 3940 //\r
7a9612ce
ED
3941 if (Question->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
3942 RequestElement = StrStr (ConfigResp, Question->VariableName);\r
3943 if (RequestElement != NULL) {\r
3944 //\r
3945 // Skip the "VariableName=" field.\r
3946 //\r
3947 RequestElement += StrLen (Question->VariableName) + 1;\r
3948 }\r
ee31d1be 3949\r
7a9612ce 3950 return RequestElement;\r
ee31d1be
ED
3951 }\r
3952\r
3953 //\r
7a9612ce 3954 // Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER\r
ee31d1be 3955 //\r
7a9612ce 3956\r
f3587039
DB
3957 //\r
3958 // Convert all hex digits in ConfigResp to lower case before searching.\r
3959 //\r
3960 HiiToLower (ConfigResp);\r
3961\r
ee31d1be 3962 //\r
7a9612ce 3963 // 1. Directly use Question->BlockName to find.\r
ee31d1be 3964 //\r
7a9612ce
ED
3965 RequestElement = StrStr (ConfigResp, Question->BlockName);\r
3966 if (RequestElement != NULL) {\r
3967 //\r
3968 // Skip the "Question->BlockName&VALUE=" field.\r
3969 //\r
3970 RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");\r
3971 return RequestElement;\r
7248790e 3972 }\r
d1102dba 3973\r
ee31d1be 3974 //\r
7a9612ce 3975 // 2. Change all hex digits in Question->BlockName to lower and compare again.\r
ee31d1be 3976 //\r
1436aea4 3977 BlockData = AllocateCopyPool (StrSize (Question->BlockName), Question->BlockName);\r
7a9612ce
ED
3978 ASSERT (BlockData != NULL);\r
3979 HiiToLower (BlockData);\r
3980 RequestElement = StrStr (ConfigResp, BlockData);\r
3981 FreePool (BlockData);\r
3982\r
3983 if (RequestElement != NULL) {\r
ee31d1be 3984 //\r
7a9612ce 3985 // Skip the "Question->BlockName&VALUE=" field.\r
ee31d1be 3986 //\r
7a9612ce 3987 RequestElement += StrLen (Question->BlockName) + StrLen (L"&VALUE=");\r
ee31d1be 3988 }\r
7a9612ce
ED
3989\r
3990 return RequestElement;\r
3991}\r
3992\r
3993/**\r
3994 Get Question default value from AltCfg string.\r
3995\r
3996 @param FormSet The form set.\r
3997 @param Form The form\r
3998 @param Question The question.\r
3999\r
4000 @retval EFI_SUCCESS Question is reset to default value.\r
4001\r
4002**/\r
4003EFI_STATUS\r
4004GetDefaultValueFromAltCfg (\r
1436aea4
MK
4005 IN FORM_BROWSER_FORMSET *FormSet,\r
4006 IN FORM_BROWSER_FORM *Form,\r
4007 IN OUT FORM_BROWSER_STATEMENT *Question\r
7a9612ce 4008 )\r
d1102dba 4009{\r
7a9612ce
ED
4010 BROWSER_STORAGE *Storage;\r
4011 FORMSET_STORAGE *FormSetStorage;\r
4012 CHAR16 *ConfigResp;\r
4013 CHAR16 *Value;\r
4014 LIST_ENTRY *Link;\r
4015 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
4016\r
4017 Storage = Question->Storage;\r
4018 if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
4019 return EFI_NOT_FOUND;\r
ee31d1be 4020 }\r
ee31d1be
ED
4021\r
4022 //\r
7a9612ce
ED
4023 // Try to get AltCfg string from form. If not found it, then\r
4024 // try to get it from formset.\r
ee31d1be 4025 //\r
1436aea4
MK
4026 ConfigResp = NULL;\r
4027 Link = GetFirstNode (&Form->ConfigRequestHead);\r
7a9612ce
ED
4028 while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
4029 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
1436aea4 4030 Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
ee31d1be 4031\r
7a9612ce
ED
4032 if (Storage == ConfigInfo->Storage) {\r
4033 ConfigResp = ConfigInfo->ConfigAltResp;\r
4034 break;\r
ee31d1be 4035 }\r
7a9612ce
ED
4036 }\r
4037\r
4038 if (ConfigResp == NULL) {\r
4039 Link = GetFirstNode (&FormSet->StorageListHead);\r
4040 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
4041 FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
1436aea4 4042 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
7a9612ce
ED
4043\r
4044 if (Storage == FormSetStorage->BrowserStorage) {\r
4045 ConfigResp = FormSetStorage->ConfigAltResp;\r
4046 break;\r
25361615
ED
4047 }\r
4048 }\r
4049 }\r
b9feb4bd 4050\r
7a9612ce
ED
4051 if (ConfigResp == NULL) {\r
4052 return EFI_NOT_FOUND;\r
7c6c064c
ED
4053 }\r
4054\r
7a9612ce
ED
4055 Value = GetOffsetFromConfigResp (Question, ConfigResp);\r
4056 if (Value == NULL) {\r
4057 return EFI_NOT_FOUND;\r
7c6c064c
ED
4058 }\r
4059\r
7a9612ce 4060 return BufferToValue (Question, Value);\r
7c6c064c
ED
4061}\r
4062\r
4063/**\r
4064 Get default Id value used for browser.\r
4065\r
4066 @param DefaultId The default id value used by hii.\r
4067\r
4068 @retval Browser used default value.\r
4069\r
4070**/\r
4071INTN\r
4072GetDefaultIdForCallBack (\r
1436aea4 4073 UINTN DefaultId\r
7c6c064c 4074 )\r
d1102dba 4075{\r
7c6c064c
ED
4076 if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
4077 return EFI_BROWSER_ACTION_DEFAULT_STANDARD;\r
4078 } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
4079 return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;\r
4080 } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {\r
4081 return EFI_BROWSER_ACTION_DEFAULT_SAFE;\r
1436aea4 4082 } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000)) {\r
7c6c064c 4083 return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;\r
1436aea4 4084 } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000)) {\r
7c6c064c 4085 return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;\r
1436aea4 4086 } else if ((DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN) && (DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000)) {\r
7c6c064c
ED
4087 return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;\r
4088 } else {\r
4089 return -1;\r
4090 }\r
4091}\r
4092\r
7c6c064c
ED
4093/**\r
4094 Return data element in an Array by its Index.\r
4095\r
4096 @param Array The data array.\r
4097 @param Type Type of the data in this array.\r
4098 @param Index Zero based index for data in this array.\r
4099\r
4100 @retval Value The data to be returned\r
4101\r
4102**/\r
4103UINT64\r
4104GetArrayData (\r
1436aea4
MK
4105 IN VOID *Array,\r
4106 IN UINT8 Type,\r
4107 IN UINTN Index\r
7c6c064c
ED
4108 )\r
4109{\r
1436aea4 4110 UINT64 Data;\r
7c6c064c
ED
4111\r
4112 ASSERT (Array != NULL);\r
4113\r
4114 Data = 0;\r
4115 switch (Type) {\r
1436aea4
MK
4116 case EFI_IFR_TYPE_NUM_SIZE_8:\r
4117 Data = (UINT64)*(((UINT8 *)Array) + Index);\r
4118 break;\r
7c6c064c 4119\r
1436aea4
MK
4120 case EFI_IFR_TYPE_NUM_SIZE_16:\r
4121 Data = (UINT64)*(((UINT16 *)Array) + Index);\r
4122 break;\r
7c6c064c 4123\r
1436aea4
MK
4124 case EFI_IFR_TYPE_NUM_SIZE_32:\r
4125 Data = (UINT64)*(((UINT32 *)Array) + Index);\r
4126 break;\r
7c6c064c 4127\r
1436aea4
MK
4128 case EFI_IFR_TYPE_NUM_SIZE_64:\r
4129 Data = (UINT64)*(((UINT64 *)Array) + Index);\r
4130 break;\r
7c6c064c 4131\r
1436aea4
MK
4132 default:\r
4133 break;\r
7c6c064c
ED
4134 }\r
4135\r
4136 return Data;\r
4137}\r
4138\r
7c6c064c
ED
4139/**\r
4140 Set value of a data element in an Array by its Index.\r
4141\r
4142 @param Array The data array.\r
4143 @param Type Type of the data in this array.\r
4144 @param Index Zero based index for data in this array.\r
4145 @param Value The value to be set.\r
4146\r
4147**/\r
4148VOID\r
4149SetArrayData (\r
1436aea4
MK
4150 IN VOID *Array,\r
4151 IN UINT8 Type,\r
4152 IN UINTN Index,\r
4153 IN UINT64 Value\r
7c6c064c
ED
4154 )\r
4155{\r
7c6c064c 4156 ASSERT (Array != NULL);\r
b9feb4bd 4157\r
7c6c064c 4158 switch (Type) {\r
1436aea4
MK
4159 case EFI_IFR_TYPE_NUM_SIZE_8:\r
4160 *(((UINT8 *)Array) + Index) = (UINT8)Value;\r
4161 break;\r
25361615 4162\r
1436aea4
MK
4163 case EFI_IFR_TYPE_NUM_SIZE_16:\r
4164 *(((UINT16 *)Array) + Index) = (UINT16)Value;\r
4165 break;\r
7c6c064c 4166\r
1436aea4
MK
4167 case EFI_IFR_TYPE_NUM_SIZE_32:\r
4168 *(((UINT32 *)Array) + Index) = (UINT32)Value;\r
4169 break;\r
7c6c064c 4170\r
1436aea4
MK
4171 case EFI_IFR_TYPE_NUM_SIZE_64:\r
4172 *(((UINT64 *)Array) + Index) = (UINT64)Value;\r
4173 break;\r
7c6c064c 4174\r
1436aea4
MK
4175 default:\r
4176 break;\r
7c6c064c 4177 }\r
ee31d1be
ED
4178}\r
4179\r
4180/**\r
7c6c064c 4181 Search an Option of a Question by its value.\r
ee31d1be 4182\r
7c6c064c
ED
4183 @param Question The Question\r
4184 @param OptionValue Value for Option to be searched.\r
ee31d1be 4185\r
7c6c064c
ED
4186 @retval Pointer Pointer to the found Option.\r
4187 @retval NULL Option not found.\r
ee31d1be
ED
4188\r
4189**/\r
7c6c064c
ED
4190QUESTION_OPTION *\r
4191ValueToOption (\r
1436aea4
MK
4192 IN FORM_BROWSER_STATEMENT *Question,\r
4193 IN EFI_HII_VALUE *OptionValue\r
ee31d1be 4194 )\r
7c6c064c
ED
4195{\r
4196 LIST_ENTRY *Link;\r
4197 QUESTION_OPTION *Option;\r
4198 INTN Result;\r
4199\r
4200 Link = GetFirstNode (&Question->OptionListHead);\r
4201 while (!IsNull (&Question->OptionListHead, Link)) {\r
4202 Option = QUESTION_OPTION_FROM_LINK (Link);\r
4203\r
4204 if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
4205 //\r
4206 // Check the suppressif condition, only a valid option can be return.\r
4207 //\r
4208 if ((Option->SuppressExpression == NULL) ||\r
1436aea4
MK
4209 ((EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)))\r
4210 {\r
7c6c064c
ED
4211 return Option;\r
4212 }\r
4213 }\r
4214\r
4215 Link = GetNextNode (&Question->OptionListHead, Link);\r
ee31d1be 4216 }\r
7c6c064c
ED
4217\r
4218 return NULL;\r
ee31d1be 4219}\r
7936fb6a 4220\r
4221/**\r
4222 Reset Question to its default value.\r
4223\r
4224 @param FormSet The form set.\r
4225 @param Form The form.\r
4226 @param Question The question.\r
4227 @param DefaultId The Class of the default.\r
4228\r
4229 @retval EFI_SUCCESS Question is reset to default value.\r
4230\r
4231**/\r
4232EFI_STATUS\r
4233GetQuestionDefault (\r
1436aea4
MK
4234 IN FORM_BROWSER_FORMSET *FormSet,\r
4235 IN FORM_BROWSER_FORM *Form,\r
4236 IN FORM_BROWSER_STATEMENT *Question,\r
4237 IN UINT16 DefaultId\r
7936fb6a 4238 )\r
4239{\r
1436aea4
MK
4240 EFI_STATUS Status;\r
4241 LIST_ENTRY *Link;\r
4242 QUESTION_DEFAULT *Default;\r
4243 QUESTION_OPTION *Option;\r
4244 EFI_HII_VALUE *HiiValue;\r
4245 UINT8 Index;\r
4246 EFI_STRING StrValue;\r
ee31d1be
ED
4247 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
4248 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
4249 INTN Action;\r
061d5462 4250 CHAR16 *NewString;\r
7f36d629 4251 EFI_IFR_TYPE_VALUE *TypeValue;\r
75596726
DB
4252 UINT16 OriginalDefaultId;\r
4253 FORMSET_DEFAULTSTORE *DefaultStore;\r
4254 LIST_ENTRY *DefaultLink;\r
7936fb6a 4255\r
1436aea4
MK
4256 Status = EFI_NOT_FOUND;\r
4257 StrValue = NULL;\r
4258 OriginalDefaultId = DefaultId;\r
4259 DefaultLink = GetFirstNode (&FormSet->DefaultStoreListHead);\r
7936fb6a 4260\r
4261 //\r
4262 // Statement don't have storage, skip them\r
4263 //\r
4264 if (Question->QuestionId == 0) {\r
4265 return Status;\r
4266 }\r
4267\r
4268 //\r
ee31d1be
ED
4269 // There are Five ways to specify default value for a Question:\r
4270 // 1, use call back function (highest priority)\r
4271 // 2, use ExtractConfig function\r
d1102dba 4272 // 3, use nested EFI_IFR_DEFAULT\r
ee31d1be
ED
4273 // 4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
4274 // 5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
7936fb6a 4275 //\r
75596726 4276ReGetDefault:\r
1436aea4 4277 HiiValue = &Question->HiiValue;\r
7f36d629 4278 TypeValue = &HiiValue->Value;\r
fa8ee0ad 4279 if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
7f36d629
DB
4280 //\r
4281 // For orderedlist, need to pass the BufferValue to Callback function.\r
4282 //\r
1436aea4 4283 TypeValue = (EFI_IFR_TYPE_VALUE *)Question->BufferValue;\r
7f36d629 4284 }\r
7936fb6a 4285\r
ee31d1be
ED
4286 //\r
4287 // Get Question defaut value from call back function.\r
4288 //\r
4289 ConfigAccess = FormSet->ConfigAccess;\r
1436aea4 4290 Action = GetDefaultIdForCallBack (DefaultId);\r
ee31d1be
ED
4291 if ((Action > 0) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {\r
4292 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1436aea4
MK
4293 Status = ConfigAccess->Callback (\r
4294 ConfigAccess,\r
4295 Action,\r
4296 Question->QuestionId,\r
4297 HiiValue->Type,\r
4298 TypeValue,\r
4299 &ActionRequest\r
4300 );\r
ee31d1be 4301 if (!EFI_ERROR (Status)) {\r
061d5462
ED
4302 if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
4303 NewString = GetToken (Question->HiiValue.Value.string, FormSet->HiiHandle);\r
4304 ASSERT (NewString != NULL);\r
4305\r
4306 ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth);\r
4307 if (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth) {\r
05b2f9c9 4308 ZeroMem (Question->BufferValue, Question->StorageWidth);\r
061d5462
ED
4309 CopyMem (Question->BufferValue, NewString, StrSize (NewString));\r
4310 } else {\r
4311 CopyMem (Question->BufferValue, NewString, Question->StorageWidth);\r
4312 }\r
4313\r
4314 FreePool (NewString);\r
4315 }\r
1436aea4 4316\r
ee31d1be
ED
4317 return Status;\r
4318 }\r
4319 }\r
4320\r
4321 //\r
4322 // Get default value from altcfg string.\r
4323 //\r
d1102dba 4324 if (ConfigAccess != NULL) {\r
1436aea4 4325 Status = GetDefaultValueFromAltCfg (FormSet, Form, Question);\r
ee31d1be 4326 if (!EFI_ERROR (Status)) {\r
1436aea4 4327 return Status;\r
ee31d1be
ED
4328 }\r
4329 }\r
4330\r
7936fb6a 4331 //\r
4332 // EFI_IFR_DEFAULT has highest priority\r
4333 //\r
4334 if (!IsListEmpty (&Question->DefaultListHead)) {\r
4335 Link = GetFirstNode (&Question->DefaultListHead);\r
4336 while (!IsNull (&Question->DefaultListHead, Link)) {\r
4337 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
4338\r
4339 if (Default->DefaultId == DefaultId) {\r
4340 if (Default->ValueExpression != NULL) {\r
4341 //\r
4342 // Default is provided by an Expression, evaluate it\r
4343 //\r
4344 Status = EvaluateExpression (FormSet, Form, Default->ValueExpression);\r
4345 if (EFI_ERROR (Status)) {\r
4346 return Status;\r
4347 }\r
4348\r
901ba0e7
ED
4349 if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
4350 ASSERT (HiiValue->Type == EFI_IFR_TYPE_BUFFER && Question->BufferValue != NULL);\r
4351 if (Question->StorageWidth > Default->ValueExpression->Result.BufferLen) {\r
4352 CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen);\r
4353 Question->HiiValue.BufferLen = Default->ValueExpression->Result.BufferLen;\r
4354 } else {\r
4355 CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Question->StorageWidth);\r
4356 Question->HiiValue.BufferLen = Question->StorageWidth;\r
4357 }\r
1436aea4 4358\r
901ba0e7
ED
4359 FreePool (Default->ValueExpression->Result.Buffer);\r
4360 }\r
1436aea4 4361\r
901ba0e7 4362 HiiValue->Type = Default->ValueExpression->Result.Type;\r
d1102dba 4363 CopyMem (&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE));\r
7936fb6a 4364 } else {\r
4365 //\r
4366 // Default value is embedded in EFI_IFR_DEFAULT\r
4367 //\r
0b567d18
ED
4368 if (Default->Value.Type == EFI_IFR_TYPE_BUFFER) {\r
4369 ASSERT (HiiValue->Buffer != NULL);\r
4370 CopyMem (HiiValue->Buffer, Default->Value.Buffer, Default->Value.BufferLen);\r
4371 } else {\r
4372 CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
4373 }\r
7936fb6a 4374 }\r
4375\r
086cd2c8
LG
4376 if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
4377 StrValue = HiiGetString (FormSet->HiiHandle, HiiValue->Value.string, NULL);\r
4378 if (StrValue == NULL) {\r
4379 return EFI_NOT_FOUND;\r
4380 }\r
1436aea4 4381\r
ba944801 4382 if (Question->StorageWidth > StrSize (StrValue)) {\r
05b2f9c9 4383 ZeroMem (Question->BufferValue, Question->StorageWidth);\r
ba944801
ED
4384 CopyMem (Question->BufferValue, StrValue, StrSize (StrValue));\r
4385 } else {\r
4386 CopyMem (Question->BufferValue, StrValue, Question->StorageWidth);\r
4387 }\r
086cd2c8
LG
4388 }\r
4389\r
7936fb6a 4390 return EFI_SUCCESS;\r
4391 }\r
4392\r
4393 Link = GetNextNode (&Question->DefaultListHead, Link);\r
4394 }\r
4395 }\r
4396\r
4397 //\r
4398 // EFI_ONE_OF_OPTION\r
4399 //\r
4400 if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
1436aea4 4401 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
7936fb6a 4402 //\r
4403 // OneOfOption could only provide Standard and Manufacturing default\r
4404 //\r
4405 Link = GetFirstNode (&Question->OptionListHead);\r
4406 while (!IsNull (&Question->OptionListHead, Link)) {\r
4407 Option = QUESTION_OPTION_FROM_LINK (Link);\r
1436aea4 4408 Link = GetNextNode (&Question->OptionListHead, Link);\r
82612023
ED
4409\r
4410 if ((Option->SuppressExpression != NULL) &&\r
1436aea4
MK
4411 (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))\r
4412 {\r
82612023
ED
4413 continue;\r
4414 }\r
7936fb6a 4415\r
4416 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) ||\r
4417 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))\r
1436aea4
MK
4418 )\r
4419 {\r
7936fb6a 4420 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
4421\r
4422 return EFI_SUCCESS;\r
4423 }\r
7936fb6a 4424 }\r
4425 }\r
4426 }\r
4427\r
4428 //\r
4429 // EFI_IFR_CHECKBOX - lowest priority\r
4430 //\r
4431 if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
1436aea4 4432 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
7936fb6a 4433 //\r
4434 // Checkbox could only provide Standard and Manufacturing default\r
4435 //\r
4436 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) ||\r
4437 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))\r
1436aea4
MK
4438 )\r
4439 {\r
7936fb6a 4440 HiiValue->Value.b = TRUE;\r
7936fb6a 4441 }\r
4442\r
4443 return EFI_SUCCESS;\r
4444 }\r
4445 }\r
4446\r
4447 //\r
75596726
DB
4448 // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.\r
4449 // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.\r
4450 // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.\r
4451 //\r
1436aea4
MK
4452 while (!IsNull (&FormSet->DefaultStoreListHead, DefaultLink)) {\r
4453 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (DefaultLink);\r
4454 DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead, DefaultLink);\r
4455 DefaultId = DefaultStore->DefaultId;\r
75596726
DB
4456 if (DefaultId == OriginalDefaultId) {\r
4457 continue;\r
4458 }\r
1436aea4 4459\r
75596726
DB
4460 goto ReGetDefault;\r
4461 }\r
4462\r
4463 //\r
4464 // For Questions without default value for all the default id in the DefaultStoreList.\r
7936fb6a 4465 //\r
48a9d5f7 4466 Status = EFI_NOT_FOUND;\r
7936fb6a 4467 switch (Question->Operand) {\r
1436aea4
MK
4468 case EFI_IFR_CHECKBOX_OP:\r
4469 HiiValue->Value.b = FALSE;\r
4470 Status = EFI_SUCCESS;\r
4471 break;\r
93e59f76 4472\r
1436aea4 4473 case EFI_IFR_NUMERIC_OP:\r
afc9bf79 4474 //\r
1436aea4 4475 // Take minimum value as numeric default value\r
afc9bf79 4476 //\r
1436aea4
MK
4477 if ((Question->Flags & EFI_IFR_DISPLAY) == 0) {\r
4478 //\r
4479 // In EFI_IFR_DISPLAY_INT_DEC type, should check value with int* type.\r
4480 //\r
4481 switch (Question->Flags & EFI_IFR_NUMERIC_SIZE) {\r
4482 case EFI_IFR_NUMERIC_SIZE_1:\r
4483 if (((INT8)HiiValue->Value.u8 < (INT8)Question->Minimum) || ((INT8)HiiValue->Value.u8 > (INT8)Question->Maximum)) {\r
4484 HiiValue->Value.u8 = (UINT8)Question->Minimum;\r
4485 Status = EFI_SUCCESS;\r
4486 }\r
4487\r
4488 break;\r
4489 case EFI_IFR_NUMERIC_SIZE_2:\r
4490 if (((INT16)HiiValue->Value.u16 < (INT16)Question->Minimum) || ((INT16)HiiValue->Value.u16 > (INT16)Question->Maximum)) {\r
4491 HiiValue->Value.u16 = (UINT16)Question->Minimum;\r
4492 Status = EFI_SUCCESS;\r
4493 }\r
4494\r
4495 break;\r
4496 case EFI_IFR_NUMERIC_SIZE_4:\r
4497 if (((INT32)HiiValue->Value.u32 < (INT32)Question->Minimum) || ((INT32)HiiValue->Value.u32 > (INT32)Question->Maximum)) {\r
4498 HiiValue->Value.u32 = (UINT32)Question->Minimum;\r
4499 Status = EFI_SUCCESS;\r
4500 }\r
4501\r
4502 break;\r
4503 case EFI_IFR_NUMERIC_SIZE_8:\r
4504 if (((INT64)HiiValue->Value.u64 < (INT64)Question->Minimum) || ((INT64)HiiValue->Value.u64 > (INT64)Question->Maximum)) {\r
4505 HiiValue->Value.u64 = Question->Minimum;\r
4506 Status = EFI_SUCCESS;\r
4507 }\r
4508\r
4509 break;\r
4510 default:\r
4511 break;\r
afc9bf79 4512 }\r
1436aea4
MK
4513 } else {\r
4514 if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > Question->Maximum)) {\r
afc9bf79 4515 HiiValue->Value.u64 = Question->Minimum;\r
1436aea4 4516 Status = EFI_SUCCESS;\r
afc9bf79 4517 }\r
afc9bf79 4518 }\r
1436aea4
MK
4519\r
4520 break;\r
4521\r
4522 case EFI_IFR_ONE_OF_OP:\r
4523 //\r
4524 // Take first oneof option as oneof's default value\r
4525 //\r
4526 if (ValueToOption (Question, HiiValue) == NULL) {\r
4527 Link = GetFirstNode (&Question->OptionListHead);\r
4528 while (!IsNull (&Question->OptionListHead, Link)) {\r
4529 Option = QUESTION_OPTION_FROM_LINK (Link);\r
4530 Link = GetNextNode (&Question->OptionListHead, Link);\r
4531\r
4532 if ((Option->SuppressExpression != NULL) &&\r
4533 (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))\r
4534 {\r
4535 continue;\r
4536 }\r
4537\r
4538 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
4539 Status = EFI_SUCCESS;\r
4540 break;\r
4541 }\r
afc9bf79 4542 }\r
cf4c5a42 4543\r
1436aea4
MK
4544 break;\r
4545\r
4546 case EFI_IFR_ORDERED_LIST_OP:\r
4547 //\r
4548 // Take option sequence in IFR as ordered list's default value\r
4549 //\r
4550 Index = 0;\r
4551 Link = GetFirstNode (&Question->OptionListHead);\r
82612023 4552 while (!IsNull (&Question->OptionListHead, Link)) {\r
1436aea4 4553 Status = EFI_SUCCESS;\r
0a1147ed 4554 Option = QUESTION_OPTION_FROM_LINK (Link);\r
1436aea4 4555 Link = GetNextNode (&Question->OptionListHead, Link);\r
82612023
ED
4556\r
4557 if ((Option->SuppressExpression != NULL) &&\r
1436aea4
MK
4558 (EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse))\r
4559 {\r
82612023
ED
4560 continue;\r
4561 }\r
4562\r
1436aea4 4563 SetArrayData (Question->BufferValue, Question->ValueType, Index, Option->Value.Value.u64);\r
7936fb6a 4564\r
1436aea4
MK
4565 Index++;\r
4566 if (Index >= Question->MaxContainers) {\r
4567 break;\r
4568 }\r
82612023 4569 }\r
7936fb6a 4570\r
1436aea4 4571 break;\r
7936fb6a 4572\r
1436aea4
MK
4573 default:\r
4574 break;\r
7936fb6a 4575 }\r
4576\r
4577 return Status;\r
4578}\r
4579\r
7a9612ce
ED
4580/**\r
4581 Get AltCfg string for current form.\r
4582\r
4583 @param FormSet Form data structure.\r
4584 @param Form Form data structure.\r
4585 @param DefaultId The Class of the default.\r
787fc2a6 4586 @param BrowserStorage The input request storage for the questions.\r
7a9612ce
ED
4587\r
4588**/\r
4589VOID\r
4590ExtractAltCfgForForm (\r
1436aea4
MK
4591 IN FORM_BROWSER_FORMSET *FormSet,\r
4592 IN FORM_BROWSER_FORM *Form,\r
4593 IN UINT16 DefaultId,\r
4594 IN BROWSER_STORAGE *BrowserStorage\r
7a9612ce
ED
4595 )\r
4596{\r
4597 EFI_STATUS Status;\r
4598 LIST_ENTRY *Link;\r
4599 CHAR16 *ConfigResp;\r
4600 CHAR16 *Progress;\r
4601 CHAR16 *Result;\r
4602 BROWSER_STORAGE *Storage;\r
4603 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
4604 FORMSET_STORAGE *FormSetStorage;\r
4605\r
4606 //\r
4607 // Check whether has get AltCfg string for this formset.\r
4608 // If yes, no need to get AltCfg for form.\r
4609 //\r
4610 Link = GetFirstNode (&FormSet->StorageListHead);\r
4611 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
4612 FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
4613 Storage = FormSetStorage->BrowserStorage;\r
1436aea4
MK
4614 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
4615 if ((BrowserStorage != NULL) && (BrowserStorage != Storage)) {\r
787fc2a6
ED
4616 continue;\r
4617 }\r
7a9612ce 4618\r
1436aea4
MK
4619 if ((Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE) &&\r
4620 (FormSetStorage->ElementCount != 0) &&\r
4621 FormSetStorage->HasCallAltCfg)\r
4622 {\r
7a9612ce
ED
4623 return;\r
4624 }\r
4625 }\r
4626\r
4627 //\r
4628 // Get AltCfg string for each form.\r
4629 //\r
4630 Link = GetFirstNode (&Form->ConfigRequestHead);\r
4631 while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
4632 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
1436aea4 4633 Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
7a9612ce
ED
4634\r
4635 Storage = ConfigInfo->Storage;\r
1436aea4 4636 if ((BrowserStorage != NULL) && (BrowserStorage != Storage)) {\r
787fc2a6
ED
4637 continue;\r
4638 }\r
4639\r
7a9612ce
ED
4640 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
4641 continue;\r
4642 }\r
4643\r
4644 //\r
4645 // 1. Skip if there is no RequestElement\r
4646 //\r
4647 if (ConfigInfo->ElementCount == 0) {\r
4648 continue;\r
4649 }\r
4650\r
4651 //\r
4652 // 2. Get value through hii config routine protocol.\r
4653 //\r
4654 Status = mHiiConfigRouting->ExtractConfig (\r
1436aea4
MK
4655 mHiiConfigRouting,\r
4656 ConfigInfo->ConfigRequest,\r
4657 &Progress,\r
4658 &Result\r
4659 );\r
7a9612ce
ED
4660 if (EFI_ERROR (Status)) {\r
4661 continue;\r
4662 }\r
4663\r
4664 //\r
4665 // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
4666 // Get the default configuration string according to the default ID.\r
4667 //\r
4668 Status = mHiiConfigRouting->GetAltConfig (\r
4669 mHiiConfigRouting,\r
4670 Result,\r
4671 &Storage->Guid,\r
4672 Storage->Name,\r
4673 NULL,\r
4674 &DefaultId, // it can be NULL to get the current setting.\r
4675 &ConfigResp\r
1436aea4 4676 );\r
7a9612ce
ED
4677 FreePool (Result);\r
4678 if (EFI_ERROR (Status)) {\r
4679 continue;\r
4680 }\r
4681\r
4682 ConfigInfo->ConfigAltResp = ConfigResp;\r
4683 }\r
4684}\r
4685\r
4686/**\r
4687 Clean AltCfg string for current form.\r
4688\r
4689 @param Form Form data structure.\r
4690\r
4691**/\r
4692VOID\r
4693CleanAltCfgForForm (\r
1436aea4 4694 IN FORM_BROWSER_FORM *Form\r
7a9612ce
ED
4695 )\r
4696{\r
1436aea4 4697 LIST_ENTRY *Link;\r
7a9612ce
ED
4698 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;\r
4699\r
4700 Link = GetFirstNode (&Form->ConfigRequestHead);\r
4701 while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
4702 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
1436aea4 4703 Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
7a9612ce
ED
4704\r
4705 if (ConfigInfo->ConfigAltResp != NULL) {\r
4706 FreePool (ConfigInfo->ConfigAltResp);\r
4707 ConfigInfo->ConfigAltResp = NULL;\r
4708 }\r
4709 }\r
4710}\r
4711\r
4712/**\r
4713 Get AltCfg string for current formset.\r
4714\r
4715 @param FormSet Form data structure.\r
4716 @param DefaultId The Class of the default.\r
787fc2a6 4717 @param BrowserStorage The input request storage for the questions.\r
7a9612ce
ED
4718\r
4719**/\r
4720VOID\r
4721ExtractAltCfgForFormSet (\r
1436aea4
MK
4722 IN FORM_BROWSER_FORMSET *FormSet,\r
4723 IN UINT16 DefaultId,\r
4724 IN BROWSER_STORAGE *BrowserStorage\r
7a9612ce
ED
4725 )\r
4726{\r
1436aea4
MK
4727 EFI_STATUS Status;\r
4728 LIST_ENTRY *Link;\r
4729 CHAR16 *ConfigResp;\r
4730 CHAR16 *Progress;\r
4731 CHAR16 *Result;\r
4732 BROWSER_STORAGE *Storage;\r
4733 FORMSET_STORAGE *FormSetStorage;\r
7a9612ce
ED
4734\r
4735 Link = GetFirstNode (&FormSet->StorageListHead);\r
4736 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
4737 FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
4738 Storage = FormSetStorage->BrowserStorage;\r
1436aea4 4739 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
7a9612ce 4740\r
1436aea4 4741 if ((BrowserStorage != NULL) && (BrowserStorage != Storage)) {\r
787fc2a6
ED
4742 continue;\r
4743 }\r
4744\r
7a9612ce
ED
4745 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
4746 continue;\r
4747 }\r
4748\r
4749 //\r
4750 // 1. Skip if there is no RequestElement\r
4751 //\r
4752 if (FormSetStorage->ElementCount == 0) {\r
4753 continue;\r
4754 }\r
4755\r
787fc2a6
ED
4756 FormSetStorage->HasCallAltCfg = TRUE;\r
4757\r
7a9612ce
ED
4758 //\r
4759 // 2. Get value through hii config routine protocol.\r
4760 //\r
4761 Status = mHiiConfigRouting->ExtractConfig (\r
1436aea4
MK
4762 mHiiConfigRouting,\r
4763 FormSetStorage->ConfigRequest,\r
4764 &Progress,\r
4765 &Result\r
4766 );\r
7a9612ce
ED
4767 if (EFI_ERROR (Status)) {\r
4768 continue;\r
4769 }\r
4770\r
4771 //\r
4772 // 3. Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)\r
4773 // Get the default configuration string according to the default ID.\r
4774 //\r
4775 Status = mHiiConfigRouting->GetAltConfig (\r
4776 mHiiConfigRouting,\r
4777 Result,\r
4778 &Storage->Guid,\r
4779 Storage->Name,\r
4780 NULL,\r
4781 &DefaultId, // it can be NULL to get the current setting.\r
4782 &ConfigResp\r
1436aea4 4783 );\r
7a9612ce
ED
4784\r
4785 FreePool (Result);\r
4786 if (EFI_ERROR (Status)) {\r
4787 continue;\r
4788 }\r
4789\r
4790 FormSetStorage->ConfigAltResp = ConfigResp;\r
4791 }\r
7a9612ce
ED
4792}\r
4793\r
4794/**\r
4795 Clean AltCfg string for current formset.\r
4796\r
4797 @param FormSet Form data structure.\r
4798\r
4799**/\r
4800VOID\r
4801CleanAltCfgForFormSet (\r
1436aea4 4802 IN FORM_BROWSER_FORMSET *FormSet\r
7a9612ce
ED
4803 )\r
4804{\r
1436aea4
MK
4805 LIST_ENTRY *Link;\r
4806 FORMSET_STORAGE *FormSetStorage;\r
7a9612ce
ED
4807\r
4808 Link = GetFirstNode (&FormSet->StorageListHead);\r
4809 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
4810 FormSetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
1436aea4 4811 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
7a9612ce
ED
4812\r
4813 if (FormSetStorage->ConfigAltResp != NULL) {\r
4814 FreePool (FormSetStorage->ConfigAltResp);\r
4815 FormSetStorage->ConfigAltResp = NULL;\r
4816 }\r
787fc2a6
ED
4817\r
4818 FormSetStorage->HasCallAltCfg = FALSE;\r
7a9612ce
ED
4819 }\r
4820}\r
7936fb6a 4821\r
4822/**\r
9776099f 4823 Reset Questions to their initial value or default value in a Form, Formset or System.\r
7936fb6a 4824\r
d1102dba 4825 GetDefaultValueScope parameter decides which questions will reset\r
09cdd7d2
ED
4826 to its default value.\r
4827\r
7936fb6a 4828 @param FormSet FormSet data structure.\r
48a9d5f7 4829 @param Form Form data structure.\r
7936fb6a 4830 @param DefaultId The Class of the default.\r
48a9d5f7 4831 @param SettingScope Setting Scope for Default action.\r
09cdd7d2 4832 @param GetDefaultValueScope Get default value scope.\r
3347d410 4833 @param Storage Get default value only for this storage.\r
9776099f
ED
4834 @param RetrieveValueFirst Whether call the retrieve call back to\r
4835 get the initial value before get default\r
4836 value.\r
787fc2a6 4837 @param SkipGetAltCfg Whether skip the get altcfg string process.\r
7936fb6a 4838\r
4839 @retval EFI_SUCCESS The function completed successfully.\r
48a9d5f7 4840 @retval EFI_UNSUPPORTED Unsupport SettingScope.\r
7936fb6a 4841\r
4842**/\r
4843EFI_STATUS\r
48a9d5f7 4844ExtractDefault (\r
1436aea4
MK
4845 IN FORM_BROWSER_FORMSET *FormSet,\r
4846 IN FORM_BROWSER_FORM *Form,\r
4847 IN UINT16 DefaultId,\r
4848 IN BROWSER_SETTING_SCOPE SettingScope,\r
4849 IN BROWSER_GET_DEFAULT_VALUE GetDefaultValueScope,\r
4850 IN BROWSER_STORAGE *Storage OPTIONAL,\r
4851 IN BOOLEAN RetrieveValueFirst,\r
4852 IN BOOLEAN SkipGetAltCfg\r
7936fb6a 4853 )\r
4854{\r
4855 EFI_STATUS Status;\r
4f33c838 4856 LIST_ENTRY *FormLink;\r
48a9d5f7 4857 LIST_ENTRY *Link;\r
7936fb6a 4858 FORM_BROWSER_STATEMENT *Question;\r
48a9d5f7 4859 FORM_BROWSER_FORMSET *LocalFormSet;\r
6e74560f 4860 FORM_BROWSER_FORMSET *OldFormSet;\r
7936fb6a 4861\r
9776099f
ED
4862 Status = EFI_SUCCESS;\r
4863\r
48a9d5f7
LG
4864 //\r
4865 // Check the supported setting level.\r
4866 //\r
1436aea4 4867 if ((SettingScope >= MaxLevel) || (GetDefaultValueScope >= GetDefaultForMax)) {\r
09cdd7d2
ED
4868 return EFI_UNSUPPORTED;\r
4869 }\r
4870\r
1436aea4 4871 if ((GetDefaultValueScope == GetDefaultForStorage) && (Storage == NULL)) {\r
48a9d5f7
LG
4872 return EFI_UNSUPPORTED;\r
4873 }\r
7a9612ce 4874\r
48a9d5f7 4875 if (SettingScope == FormLevel) {\r
7a9612ce
ED
4876 //\r
4877 // Prepare the AltCfg String for form.\r
4878 //\r
787fc2a6
ED
4879 if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
4880 ExtractAltCfgForForm (FormSet, Form, DefaultId, Storage);\r
4881 }\r
7a9612ce 4882\r
8d00a0f1 4883 //\r
4f33c838 4884 // Extract Form default\r
8d00a0f1 4885 //\r
48a9d5f7
LG
4886 Link = GetFirstNode (&Form->StatementListHead);\r
4887 while (!IsNull (&Form->StatementListHead, Link)) {\r
4888 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1436aea4 4889 Link = GetNextNode (&Form->StatementListHead, Link);\r
3347d410
ED
4890\r
4891 //\r
4892 // If get default value only for this storage, check the storage first.\r
4893 //\r
09cdd7d2
ED
4894 if ((GetDefaultValueScope == GetDefaultForStorage) && (Question->Storage != Storage)) {\r
4895 continue;\r
4896 }\r
4897\r
4898 //\r
4899 // If get default value only for no storage question, just skip the question which has storage.\r
4900 //\r
4901 if ((GetDefaultValueScope == GetDefaultForNoStorage) && (Question->Storage != NULL)) {\r
3347d410
ED
4902 continue;\r
4903 }\r
4904\r
4f33c838
ED
4905 //\r
4906 // If Question is disabled, don't reset it to default\r
4907 //\r
31585af4 4908 if (Question->Expression != NULL) {\r
1436aea4 4909 if (EvaluateExpressionList (Question->Expression, TRUE, FormSet, Form) == ExpressDisable) {\r
4f33c838
ED
4910 continue;\r
4911 }\r
8d00a0f1 4912 }\r
9776099f
ED
4913\r
4914 if (RetrieveValueFirst) {\r
4915 //\r
4916 // Call the Retrieve call back to get the initial question value.\r
4917 //\r
1436aea4 4918 Status = ProcessRetrieveForQuestion (FormSet->ConfigAccess, Question, FormSet);\r
9776099f
ED
4919 }\r
4920\r
4f33c838 4921 //\r
9776099f 4922 // If not request to get the initial value or get initial value fail, then get default value.\r
4f33c838 4923 //\r
9776099f
ED
4924 if (!RetrieveValueFirst || EFI_ERROR (Status)) {\r
4925 Status = GetQuestionDefault (FormSet, Form, Question, DefaultId);\r
4926 if (EFI_ERROR (Status)) {\r
4927 continue;\r
4928 }\r
4f33c838 4929 }\r
9776099f 4930\r
4f33c838
ED
4931 //\r
4932 // Synchronize Buffer storage's Edit buffer\r
4933 //\r
4934 if ((Question->Storage != NULL) &&\r
1436aea4
MK
4935 (Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE))\r
4936 {\r
816a7110 4937 SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
48a9d5f7
LG
4938 }\r
4939 }\r
7a9612ce
ED
4940\r
4941 //\r
4942 // Clean the AltCfg String.\r
4943 //\r
787fc2a6 4944 if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
1436aea4 4945 CleanAltCfgForForm (Form);\r
787fc2a6 4946 }\r
48a9d5f7 4947 } else if (SettingScope == FormSetLevel) {\r
7a9612ce
ED
4948 //\r
4949 // Prepare the AltCfg String for formset.\r
4950 //\r
787fc2a6
ED
4951 if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
4952 ExtractAltCfgForFormSet (FormSet, DefaultId, Storage);\r
4953 }\r
7a9612ce 4954\r
48a9d5f7
LG
4955 FormLink = GetFirstNode (&FormSet->FormListHead);\r
4956 while (!IsNull (&FormSet->FormListHead, FormLink)) {\r
4957 Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
787fc2a6 4958 ExtractDefault (FormSet, Form, DefaultId, FormLevel, GetDefaultValueScope, Storage, RetrieveValueFirst, SkipGetAltCfg);\r
48a9d5f7
LG
4959 FormLink = GetNextNode (&FormSet->FormListHead, FormLink);\r
4960 }\r
7a9612ce
ED
4961\r
4962 //\r
4963 // Clean the AltCfg String.\r
4964 //\r
787fc2a6
ED
4965 if (!SkipGetAltCfg && (GetDefaultValueScope != GetDefaultForNoStorage)) {\r
4966 CleanAltCfgForFormSet (FormSet);\r
4967 }\r
48a9d5f7
LG
4968 } else if (SettingScope == SystemLevel) {\r
4969 //\r
7c6c064c 4970 // Preload all Hii formset.\r
48a9d5f7 4971 //\r
1436aea4 4972 LoadAllHiiFormset ();\r
6e74560f
ED
4973\r
4974 OldFormSet = mSystemLevelFormSet;\r
4975\r
48a9d5f7
LG
4976 //\r
4977 // Set Default Value for each FormSet in the maintain list.\r
4978 //\r
4979 Link = GetFirstNode (&gBrowserFormSetList);\r
4980 while (!IsNull (&gBrowserFormSetList, Link)) {\r
4981 LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
1436aea4
MK
4982 Link = GetNextNode (&gBrowserFormSetList, Link);\r
4983 if (!ValidateFormSet (LocalFormSet)) {\r
938baa1f
ED
4984 continue;\r
4985 }\r
6e74560f
ED
4986\r
4987 mSystemLevelFormSet = LocalFormSet;\r
4988\r
787fc2a6 4989 ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel, GetDefaultValueScope, Storage, RetrieveValueFirst, SkipGetAltCfg);\r
7936fb6a 4990 }\r
6e74560f
ED
4991\r
4992 mSystemLevelFormSet = OldFormSet;\r
7936fb6a 4993 }\r
4994\r
4995 return EFI_SUCCESS;\r
4996}\r
4997\r
7c6c064c
ED
4998/**\r
4999 Validate whether this question's value has changed.\r
5000\r
5001 @param FormSet FormSet data structure.\r
5002 @param Form Form data structure.\r
5003 @param Question Question to be initialized.\r
5004 @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.\r
5005\r
5006 @retval TRUE Question's value has changed.\r
5007 @retval FALSE Question's value has not changed\r
5008\r
5009**/\r
5010BOOLEAN\r
5011IsQuestionValueChanged (\r
1436aea4
MK
5012 IN FORM_BROWSER_FORMSET *FormSet,\r
5013 IN FORM_BROWSER_FORM *Form,\r
5014 IN OUT FORM_BROWSER_STATEMENT *Question,\r
5015 IN GET_SET_QUESTION_VALUE_WITH GetValueFrom\r
7c6c064c
ED
5016 )\r
5017{\r
1436aea4
MK
5018 EFI_HII_VALUE BackUpValue;\r
5019 CHAR8 *BackUpBuffer;\r
5020 EFI_HII_VALUE BackUpValue2;\r
5021 CHAR8 *BackUpBuffer2;\r
5022 EFI_STATUS Status;\r
5023 BOOLEAN ValueChanged;\r
5024 UINTN BufferWidth;\r
7c6c064c
ED
5025\r
5026 //\r
5027 // For quetion without storage, always mark it as data not changed.\r
5028 //\r
1436aea4 5029 if ((Question->Storage == NULL) && (Question->Operand != EFI_IFR_TIME_OP) && (Question->Operand != EFI_IFR_DATE_OP)) {\r
7c6c064c
ED
5030 return FALSE;\r
5031 }\r
5032\r
1436aea4 5033 BackUpBuffer = NULL;\r
4d4deaac 5034 BackUpBuffer2 = NULL;\r
1436aea4 5035 ValueChanged = FALSE;\r
7c6c064c
ED
5036\r
5037 switch (Question->Operand) {\r
5038 case EFI_IFR_ORDERED_LIST_OP:\r
5039 BufferWidth = Question->StorageWidth;\r
5040 BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
5041 ASSERT (BackUpBuffer != NULL);\r
5042 break;\r
5043\r
5044 case EFI_IFR_STRING_OP:\r
5045 case EFI_IFR_PASSWORD_OP:\r
1436aea4 5046 BufferWidth = (UINTN)Question->Maximum * sizeof (CHAR16);\r
7c6c064c
ED
5047 BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
5048 ASSERT (BackUpBuffer != NULL);\r
5049 break;\r
5050\r
5051 default:\r
5052 BufferWidth = 0;\r
5053 break;\r
5054 }\r
1436aea4 5055\r
7c6c064c
ED
5056 CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
5057\r
4d4deaac
ED
5058 if (GetValueFrom == GetSetValueWithBothBuffer) {\r
5059 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
1436aea4 5060 ASSERT_EFI_ERROR (Status);\r
7c6c064c 5061\r
4d4deaac
ED
5062 switch (Question->Operand) {\r
5063 case EFI_IFR_ORDERED_LIST_OP:\r
1436aea4 5064 BufferWidth = Question->StorageWidth;\r
4d4deaac
ED
5065 BackUpBuffer2 = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
5066 ASSERT (BackUpBuffer2 != NULL);\r
5067 break;\r
5068\r
5069 case EFI_IFR_STRING_OP:\r
5070 case EFI_IFR_PASSWORD_OP:\r
1436aea4 5071 BufferWidth = (UINTN)Question->Maximum * sizeof (CHAR16);\r
4d4deaac
ED
5072 BackUpBuffer2 = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
5073 ASSERT (BackUpBuffer2 != NULL);\r
5074 break;\r
5075\r
5076 default:\r
5077 BufferWidth = 0;\r
5078 break;\r
5079 }\r
1436aea4 5080\r
4d4deaac
ED
5081 CopyMem (&BackUpValue2, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
5082\r
5083 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);\r
1436aea4 5084 ASSERT_EFI_ERROR (Status);\r
4d4deaac 5085\r
1436aea4
MK
5086 if ((CompareMem (&BackUpValue2, &Question->HiiValue, sizeof (EFI_HII_VALUE)) != 0) ||\r
5087 (CompareMem (BackUpBuffer2, Question->BufferValue, BufferWidth) != 0))\r
5088 {\r
4d4deaac
ED
5089 ValueChanged = TRUE;\r
5090 }\r
5091 } else {\r
5092 Status = GetQuestionValue (FormSet, Form, Question, GetValueFrom);\r
1436aea4 5093 ASSERT_EFI_ERROR (Status);\r
4d4deaac 5094\r
1436aea4
MK
5095 if ((CompareMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE)) != 0) ||\r
5096 (CompareMem (BackUpBuffer, Question->BufferValue, BufferWidth) != 0))\r
5097 {\r
4d4deaac
ED
5098 ValueChanged = TRUE;\r
5099 }\r
7c6c064c
ED
5100 }\r
5101\r
5102 CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));\r
7c6c064c 5103 if (BackUpBuffer != NULL) {\r
e77d2f9d 5104 CopyMem (Question->BufferValue, BackUpBuffer, BufferWidth);\r
7c6c064c
ED
5105 FreePool (BackUpBuffer);\r
5106 }\r
5107\r
4d4deaac
ED
5108 if (BackUpBuffer2 != NULL) {\r
5109 FreePool (BackUpBuffer2);\r
5110 }\r
5111\r
892eccc8
ED
5112 Question->ValueChanged = ValueChanged;\r
5113\r
7c6c064c
ED
5114 return ValueChanged;\r
5115}\r
5116\r
7936fb6a 5117/**\r
5118 Initialize Question's Edit copy from Storage.\r
5119\r
d1102dba 5120 @param Selection Selection contains the information about\r
eccfeab1
LG
5121 the Selection, form and formset to be displayed.\r
5122 Selection action may be updated in retrieve callback.\r
7d1b202d 5123 If Selection is NULL, only initialize Question value.\r
7936fb6a 5124 @param FormSet FormSet data structure.\r
5125 @param Form Form data structure.\r
5126\r
5127 @retval EFI_SUCCESS The function completed successfully.\r
5128\r
5129**/\r
5130EFI_STATUS\r
5131LoadFormConfig (\r
1436aea4
MK
5132 IN OUT UI_MENU_SELECTION *Selection,\r
5133 IN FORM_BROWSER_FORMSET *FormSet,\r
5134 IN FORM_BROWSER_FORM *Form\r
7936fb6a 5135 )\r
5136{\r
1436aea4
MK
5137 EFI_STATUS Status;\r
5138 LIST_ENTRY *Link;\r
5139 FORM_BROWSER_STATEMENT *Question;\r
d1102dba 5140\r
7936fb6a 5141 Link = GetFirstNode (&Form->StatementListHead);\r
5142 while (!IsNull (&Form->StatementListHead, Link)) {\r
5143 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
5144\r
5145 //\r
5146 // Initialize local copy of Value for each Question\r
5147 //\r
1436aea4 5148 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == 0)) {\r
7c6c064c
ED
5149 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);\r
5150 } else {\r
5151 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
5152 }\r
1436aea4 5153\r
7936fb6a 5154 if (EFI_ERROR (Status)) {\r
5155 return Status;\r
5156 }\r
e2100bfa
ED
5157\r
5158 if ((Question->Operand == EFI_IFR_STRING_OP) || (Question->Operand == EFI_IFR_PASSWORD_OP)) {\r
1436aea4 5159 HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16 *)Question->BufferValue, NULL);\r
e2100bfa
ED
5160 }\r
5161\r
7936fb6a 5162 Link = GetNextNode (&Form->StatementListHead, Link);\r
5163 }\r
5164\r
5165 return EFI_SUCCESS;\r
5166}\r
5167\r
d66e6c16 5168/**\r
5169 Initialize Question's Edit copy from Storage for the whole Formset.\r
5170\r
d1102dba 5171 @param Selection Selection contains the information about\r
eccfeab1
LG
5172 the Selection, form and formset to be displayed.\r
5173 Selection action may be updated in retrieve callback.\r
7d1b202d 5174 If Selection is NULL, only initialize Question value.\r
d66e6c16 5175 @param FormSet FormSet data structure.\r
5176\r
5177 @retval EFI_SUCCESS The function completed successfully.\r
5178\r
5179**/\r
5180EFI_STATUS\r
5181LoadFormSetConfig (\r
1436aea4
MK
5182 IN OUT UI_MENU_SELECTION *Selection,\r
5183 IN FORM_BROWSER_FORMSET *FormSet\r
d66e6c16 5184 )\r
5185{\r
1436aea4
MK
5186 EFI_STATUS Status;\r
5187 LIST_ENTRY *Link;\r
5188 FORM_BROWSER_FORM *Form;\r
d66e6c16 5189\r
5190 Link = GetFirstNode (&FormSet->FormListHead);\r
5191 while (!IsNull (&FormSet->FormListHead, Link)) {\r
5192 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
5193\r
5194 //\r
5195 // Initialize local copy of Value for each Form\r
5196 //\r
eccfeab1 5197 Status = LoadFormConfig (Selection, FormSet, Form);\r
d66e6c16 5198 if (EFI_ERROR (Status)) {\r
5199 return Status;\r
5200 }\r
5201\r
5202 Link = GetNextNode (&FormSet->FormListHead, Link);\r
5203 }\r
5204\r
7c6c064c
ED
5205 //\r
5206 // Finished question initialization.\r
d1102dba 5207 //\r
7c6c064c
ED
5208 FormSet->QuestionInited = TRUE;\r
5209\r
d66e6c16 5210 return EFI_SUCCESS;\r
5211}\r
5212\r
0a6f8af5
ED
5213/**\r
5214 Remove the Request element from the Config Request.\r
5215\r
5216 @param Storage Pointer to the browser storage.\r
5217 @param RequestElement The pointer to the Request element.\r
5218\r
5219**/\r
5220VOID\r
5221RemoveElement (\r
1436aea4
MK
5222 IN OUT BROWSER_STORAGE *Storage,\r
5223 IN CHAR16 *RequestElement\r
0a6f8af5
ED
5224 )\r
5225{\r
1436aea4
MK
5226 CHAR16 *NewStr;\r
5227 CHAR16 *DestStr;\r
0a6f8af5
ED
5228\r
5229 ASSERT (Storage->ConfigRequest != NULL && RequestElement != NULL);\r
5230\r
5231 NewStr = StrStr (Storage->ConfigRequest, RequestElement);\r
5232\r
5233 if (NewStr == NULL) {\r
5234 return;\r
5235 }\r
5236\r
5237 //\r
5238 // Remove this element from this ConfigRequest.\r
5239 //\r
5240 DestStr = NewStr;\r
5241 NewStr += StrLen (RequestElement);\r
5242 CopyMem (DestStr, NewStr, StrSize (NewStr));\r
d1102dba
LG
5243\r
5244 Storage->SpareStrLen += StrLen (RequestElement);\r
0a6f8af5
ED
5245}\r
5246\r
5247/**\r
5248 Adjust config request in storage, remove the request elements existed in the input ConfigRequest.\r
5249\r
a35ecb75 5250 @param Storage Pointer to the formset storage.\r
0a6f8af5
ED
5251 @param ConfigRequest The pointer to the Request element.\r
5252\r
5253**/\r
5254VOID\r
5255RemoveConfigRequest (\r
1436aea4
MK
5256 FORMSET_STORAGE *Storage,\r
5257 CHAR16 *ConfigRequest\r
0a6f8af5
ED
5258 )\r
5259{\r
1436aea4
MK
5260 CHAR16 *RequestElement;\r
5261 CHAR16 *NextRequestElement;\r
5262 CHAR16 *SearchKey;\r
0a6f8af5 5263\r
7c6c064c
ED
5264 //\r
5265 // No request element in it, just return.\r
5266 //\r
5267 if (ConfigRequest == NULL) {\r
5268 return;\r
5269 }\r
5270\r
a35ecb75 5271 if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
0a6f8af5
ED
5272 //\r
5273 // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
5274 //\r
5275 SearchKey = L"&";\r
5276 } else {\r
5277 //\r
5278 // "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage\r
5279 //\r
5280 SearchKey = L"&OFFSET";\r
5281 }\r
5282\r
5283 //\r
5284 // Find SearchKey storage\r
5285 //\r
a35ecb75 5286 if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
0a6f8af5
ED
5287 RequestElement = StrStr (ConfigRequest, L"PATH");\r
5288 ASSERT (RequestElement != NULL);\r
d1102dba 5289 RequestElement = StrStr (RequestElement, SearchKey);\r
0a6f8af5
ED
5290 } else {\r
5291 RequestElement = StrStr (ConfigRequest, SearchKey);\r
5292 }\r
5293\r
5294 while (RequestElement != NULL) {\r
5295 //\r
5296 // +1 to avoid find header itself.\r
5297 //\r
5298 NextRequestElement = StrStr (RequestElement + 1, SearchKey);\r
5299\r
5300 //\r
5301 // The last Request element in configRequest string.\r
5302 //\r
5303 if (NextRequestElement != NULL) {\r
5304 //\r
5305 // Replace "&" with '\0'.\r
5306 //\r
5307 *NextRequestElement = L'\0';\r
5308 }\r
5309\r
a35ecb75 5310 RemoveElement (Storage->BrowserStorage, RequestElement);\r
0a6f8af5
ED
5311\r
5312 if (NextRequestElement != NULL) {\r
5313 //\r
5314 // Restore '&' with '\0' for later used.\r
5315 //\r
5316 *NextRequestElement = L'&';\r
5317 }\r
5318\r
5319 RequestElement = NextRequestElement;\r
5320 }\r
5321\r
5322 //\r
5323 // If no request element remain, just remove the ConfigRequest string.\r
5324 //\r
a35ecb75
ED
5325 if (StrCmp (Storage->BrowserStorage->ConfigRequest, Storage->ConfigHdr) == 0) {\r
5326 FreePool (Storage->BrowserStorage->ConfigRequest);\r
5327 Storage->BrowserStorage->ConfigRequest = NULL;\r
5328 Storage->BrowserStorage->SpareStrLen = 0;\r
0a6f8af5
ED
5329 }\r
5330}\r
5331\r
5332/**\r
5333 Base on the current formset info, clean the ConfigRequest string in browser storage.\r
5334\r
5335 @param FormSet Pointer of the FormSet\r
5336\r
5337**/\r
5338VOID\r
5339CleanBrowserStorage (\r
5340 IN OUT FORM_BROWSER_FORMSET *FormSet\r
5341 )\r
5342{\r
1436aea4
MK
5343 LIST_ENTRY *Link;\r
5344 FORMSET_STORAGE *Storage;\r
0a6f8af5
ED
5345\r
5346 Link = GetFirstNode (&FormSet->StorageListHead);\r
5347 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
5348 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
1436aea4 5349 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
0a6f8af5 5350\r
fae73624 5351 if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
1436aea4 5352 if ((Storage->ConfigRequest == NULL) || (Storage->BrowserStorage->ConfigRequest == NULL)) {\r
fae73624
ED
5353 continue;\r
5354 }\r
0a6f8af5 5355\r
a35ecb75 5356 RemoveConfigRequest (Storage, Storage->ConfigRequest);\r
1436aea4
MK
5357 } else if ((Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER) ||\r
5358 (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE))\r
5359 {\r
d1102dba 5360 if (Storage->BrowserStorage->ConfigRequest != NULL) {\r
fae73624 5361 FreePool (Storage->BrowserStorage->ConfigRequest);\r
5dc6ab16 5362 Storage->BrowserStorage->ConfigRequest = NULL;\r
fae73624 5363 }\r
1436aea4 5364\r
fae73624 5365 Storage->BrowserStorage->Initialized = FALSE;\r
0a6f8af5 5366 }\r
0a6f8af5
ED
5367 }\r
5368}\r
5369\r
efffd9c1
ED
5370/**\r
5371 Check whether current element in the ConfigReqeust string.\r
5372\r
5373 @param BrowserStorage Storage which includes ConfigReqeust.\r
5374 @param RequestElement New element need to check.\r
5375\r
5376 @retval TRUE The Element is in the ConfigReqeust string.\r
5377 @retval FALSE The Element not in the configReqeust String.\r
5378\r
5379**/\r
d1102dba 5380BOOLEAN\r
efffd9c1 5381ElementValidation (\r
1436aea4
MK
5382 BROWSER_STORAGE *BrowserStorage,\r
5383 CHAR16 *RequestElement\r
efffd9c1
ED
5384 )\r
5385{\r
5386 return StrStr (BrowserStorage->ConfigRequest, RequestElement) != NULL ? TRUE : FALSE;\r
5387}\r
5388\r
5389/**\r
5390 Append the Request element to the Config Request.\r
5391\r
5392 @param ConfigRequest Current ConfigRequest info.\r
5393 @param SpareStrLen Current remain free buffer for config reqeust.\r
5394 @param RequestElement New Request element.\r
5395\r
5396**/\r
5397VOID\r
5398AppendConfigRequest (\r
1436aea4
MK
5399 IN OUT CHAR16 **ConfigRequest,\r
5400 IN OUT UINTN *SpareStrLen,\r
5401 IN CHAR16 *RequestElement\r
efffd9c1
ED
5402 )\r
5403{\r
1436aea4
MK
5404 CHAR16 *NewStr;\r
5405 UINTN StringSize;\r
5406 UINTN StrLength;\r
5407 UINTN MaxLen;\r
efffd9c1 5408\r
1436aea4 5409 StrLength = StrLen (RequestElement);\r
5ad66ec6 5410 StringSize = (*ConfigRequest != NULL) ? StrSize (*ConfigRequest) : sizeof (CHAR16);\r
1436aea4 5411 MaxLen = StringSize / sizeof (CHAR16) + *SpareStrLen;\r
efffd9c1
ED
5412\r
5413 //\r
5414 // Append <RequestElement> to <ConfigRequest>\r
5415 //\r
5416 if (StrLength > *SpareStrLen) {\r
5417 //\r
5418 // Old String buffer is not sufficient for RequestElement, allocate a new one\r
5419 //\r
5ad66ec6
DB
5420 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;\r
5421 NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
efffd9c1
ED
5422 ASSERT (NewStr != NULL);\r
5423\r
5424 if (*ConfigRequest != NULL) {\r
5425 CopyMem (NewStr, *ConfigRequest, StringSize);\r
5426 FreePool (*ConfigRequest);\r
5427 }\r
1436aea4 5428\r
efffd9c1
ED
5429 *ConfigRequest = NewStr;\r
5430 *SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
5431 }\r
5432\r
5ad66ec6 5433 StrCatS (*ConfigRequest, MaxLen, RequestElement);\r
efffd9c1
ED
5434 *SpareStrLen -= StrLength;\r
5435}\r
5436\r
5437/**\r
5438 Adjust the config request info, remove the request elements which already in AllConfigRequest string.\r
5439\r
5440 @param Storage Form set Storage.\r
9d34cac8
ED
5441 @param Request The input request string.\r
5442 @param RespString Whether the input is ConfigRequest or ConfigResp format.\r
efffd9c1
ED
5443\r
5444 @retval TRUE Has element not covered by current used elements, need to continue to call ExtractConfig\r
5445 @retval FALSE All elements covered by current used elements.\r
5446\r
5447**/\r
d1102dba 5448BOOLEAN\r
efffd9c1 5449ConfigRequestAdjust (\r
1436aea4
MK
5450 IN BROWSER_STORAGE *Storage,\r
5451 IN CHAR16 *Request,\r
5452 IN BOOLEAN RespString\r
efffd9c1
ED
5453 )\r
5454{\r
1436aea4
MK
5455 CHAR16 *RequestElement;\r
5456 CHAR16 *NextRequestElement;\r
5457 CHAR16 *NextElementBakup;\r
5458 CHAR16 *SearchKey;\r
5459 CHAR16 *ValueKey;\r
5460 BOOLEAN RetVal;\r
5461 CHAR16 *ConfigRequest;\r
5462\r
5463 RetVal = FALSE;\r
9d34cac8
ED
5464 NextElementBakup = NULL;\r
5465 ValueKey = NULL;\r
efffd9c1 5466\r
9d34cac8
ED
5467 if (Request != NULL) {\r
5468 ConfigRequest = Request;\r
5469 } else {\r
5470 ConfigRequest = Storage->ConfigRequest;\r
5471 }\r
5472\r
5473 if (Storage->ConfigRequest == NULL) {\r
5474 Storage->ConfigRequest = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);\r
efffd9c1
ED
5475 return TRUE;\r
5476 }\r
5477\r
9d34cac8 5478 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
efffd9c1
ED
5479 //\r
5480 // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
5481 //\r
5482 SearchKey = L"&";\r
5483 } else {\r
5484 //\r
5485 // "&OFFSET=####&WIDTH=####" section for EFI_HII_VARSTORE_BUFFER storage\r
5486 //\r
5487 SearchKey = L"&OFFSET";\r
9d34cac8 5488 ValueKey = L"&VALUE";\r
efffd9c1
ED
5489 }\r
5490\r
efffd9c1
ED
5491 //\r
5492 // Find SearchKey storage\r
5493 //\r
9d34cac8
ED
5494 if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
5495 RequestElement = StrStr (ConfigRequest, L"PATH");\r
efffd9c1 5496 ASSERT (RequestElement != NULL);\r
d1102dba 5497 RequestElement = StrStr (RequestElement, SearchKey);\r
efffd9c1 5498 } else {\r
9d34cac8 5499 RequestElement = StrStr (ConfigRequest, SearchKey);\r
efffd9c1
ED
5500 }\r
5501\r
5502 while (RequestElement != NULL) {\r
5503 //\r
5504 // +1 to avoid find header itself.\r
5505 //\r
5506 NextRequestElement = StrStr (RequestElement + 1, SearchKey);\r
5507\r
5508 //\r
5509 // The last Request element in configRequest string.\r
5510 //\r
5511 if (NextRequestElement != NULL) {\r
9d34cac8 5512 if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
1436aea4 5513 NextElementBakup = NextRequestElement;\r
9d34cac8 5514 NextRequestElement = StrStr (RequestElement, ValueKey);\r
d8adff44 5515 ASSERT (NextRequestElement != NULL);\r
9d34cac8 5516 }\r
1436aea4 5517\r
efffd9c1
ED
5518 //\r
5519 // Replace "&" with '\0'.\r
5520 //\r
5521 *NextRequestElement = L'\0';\r
9d34cac8
ED
5522 } else {\r
5523 if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
1436aea4 5524 NextElementBakup = NextRequestElement;\r
9d34cac8 5525 NextRequestElement = StrStr (RequestElement, ValueKey);\r
d8adff44 5526 ASSERT (NextRequestElement != NULL);\r
9d34cac8
ED
5527 //\r
5528 // Replace "&" with '\0'.\r
5529 //\r
5530 *NextRequestElement = L'\0';\r
5531 }\r
efffd9c1 5532 }\r
d1102dba 5533\r
9d34cac8 5534 if (!ElementValidation (Storage, RequestElement)) {\r
efffd9c1
ED
5535 //\r
5536 // Add this element to the Storage->BrowserStorage->AllRequestElement.\r
5537 //\r
1436aea4 5538 AppendConfigRequest (&Storage->ConfigRequest, &Storage->SpareStrLen, RequestElement);\r
efffd9c1
ED
5539 RetVal = TRUE;\r
5540 }\r
5541\r
5542 if (NextRequestElement != NULL) {\r
5543 //\r
5544 // Restore '&' with '\0' for later used.\r
5545 //\r
5546 *NextRequestElement = L'&';\r
5547 }\r
5548\r
9d34cac8
ED
5549 if (RespString && (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
5550 RequestElement = NextElementBakup;\r
5551 } else {\r
5552 RequestElement = NextRequestElement;\r
7c6c064c 5553 }\r
efffd9c1
ED
5554 }\r
5555\r
5556 return RetVal;\r
5557}\r
5558\r
7936fb6a 5559/**\r
5560 Fill storage's edit copy with settings requested from Configuration Driver.\r
5561\r
5562 @param FormSet FormSet data structure.\r
5563 @param Storage Buffer Storage.\r
5564\r
7936fb6a 5565**/\r
7c6c064c 5566VOID\r
7936fb6a 5567LoadStorage (\r
1436aea4
MK
5568 IN FORM_BROWSER_FORMSET *FormSet,\r
5569 IN FORMSET_STORAGE *Storage\r
7936fb6a 5570 )\r
5571{\r
5572 EFI_STATUS Status;\r
5573 EFI_STRING Progress;\r
5574 EFI_STRING Result;\r
5575 CHAR16 *StrPtr;\r
98c4caa1
ED
5576 EFI_STRING ConfigRequest;\r
5577 UINTN StrLen;\r
5578\r
5579 ConfigRequest = NULL;\r
7936fb6a 5580\r
7c6c064c
ED
5581 switch (Storage->BrowserStorage->Type) {\r
5582 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
5583 return;\r
5584\r
5585 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
6e74560f 5586 if (Storage->BrowserStorage->ConfigRequest != NULL) {\r
1436aea4 5587 ConfigRequestAdjust (Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
7c6c064c
ED
5588 return;\r
5589 }\r
1436aea4 5590\r
7c6c064c 5591 break;\r
cce6230f 5592\r
7c6c064c
ED
5593 case EFI_HII_VARSTORE_BUFFER:\r
5594 case EFI_HII_VARSTORE_NAME_VALUE:\r
5595 //\r
27c304f4 5596 // Skip if there is no RequestElement.\r
7c6c064c 5597 //\r
27c304f4 5598 if (Storage->ElementCount == 0) {\r
7c6c064c
ED
5599 return;\r
5600 }\r
27c304f4
ED
5601\r
5602 //\r
d1102dba 5603 // Just update the ConfigRequest, if storage already initialized.\r
27c304f4
ED
5604 //\r
5605 if (Storage->BrowserStorage->Initialized) {\r
1436aea4 5606 ConfigRequestAdjust (Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
27c304f4
ED
5607 return;\r
5608 }\r
5609\r
fae73624 5610 Storage->BrowserStorage->Initialized = TRUE;\r
7c6c064c 5611 break;\r
7936fb6a 5612\r
7c6c064c 5613 default:\r
7248790e 5614 return;\r
7936fb6a 5615 }\r
7248790e 5616\r
27c304f4
ED
5617 if (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) {\r
5618 //\r
5619 // Create the config request string to get all fields for this storage.\r
5620 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
5621 // followed by "&OFFSET=0&WIDTH=WWWW"followed by a Null-terminator\r
5622 //\r
1436aea4 5623 StrLen = StrSize (Storage->ConfigHdr) + 20 * sizeof (CHAR16);\r
27c304f4
ED
5624 ConfigRequest = AllocateZeroPool (StrLen);\r
5625 ASSERT (ConfigRequest != NULL);\r
5626 UnicodeSPrint (\r
1436aea4
MK
5627 ConfigRequest,\r
5628 StrLen,\r
5629 L"%s&OFFSET=0&WIDTH=%04x",\r
5630 Storage->ConfigHdr,\r
5631 Storage->BrowserStorage->Size\r
5632 );\r
27c304f4
ED
5633 } else {\r
5634 ConfigRequest = Storage->ConfigRequest;\r
5635 }\r
5636\r
7248790e
ED
5637 //\r
5638 // Request current settings from Configuration Driver\r
5639 //\r
5640 Status = mHiiConfigRouting->ExtractConfig (\r
1436aea4
MK
5641 mHiiConfigRouting,\r
5642 ConfigRequest,\r
5643 &Progress,\r
5644 &Result\r
5645 );\r
7248790e
ED
5646\r
5647 //\r
5648 // If get value fail, extract default from IFR binary\r
5649 //\r
5650 if (EFI_ERROR (Status)) {\r
787fc2a6 5651 ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE, TRUE);\r
7248790e
ED
5652 } else {\r
5653 //\r
5654 // Convert Result from <ConfigAltResp> to <ConfigResp>\r
5655 //\r
5656 StrPtr = StrStr (Result, L"&GUID=");\r
5657 if (StrPtr != NULL) {\r
5658 *StrPtr = L'\0';\r
5659 }\r
d1102dba 5660\r
7248790e
ED
5661 Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
5662 FreePool (Result);\r
5663 }\r
5664\r
5665 Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
5666\r
5667 //\r
d1102dba 5668 // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer.\r
7248790e 5669 //\r
1436aea4 5670 SynchronizeStorage (Storage->BrowserStorage, NULL, TRUE);\r
98c4caa1 5671\r
27c304f4 5672 if (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) {\r
98c4caa1
ED
5673 if (ConfigRequest != NULL) {\r
5674 FreePool (ConfigRequest);\r
5675 }\r
5676 }\r
7936fb6a 5677}\r
5678\r
892eccc8
ED
5679/**\r
5680 Get Value changed status from old question.\r
5681\r
5682 @param NewFormSet FormSet data structure.\r
5683 @param OldQuestion Old question which has value changed.\r
5684\r
5685**/\r
5686VOID\r
5687SyncStatusForQuestion (\r
1436aea4
MK
5688 IN OUT FORM_BROWSER_FORMSET *NewFormSet,\r
5689 IN FORM_BROWSER_STATEMENT *OldQuestion\r
892eccc8
ED
5690 )\r
5691{\r
1436aea4
MK
5692 LIST_ENTRY *Link;\r
5693 LIST_ENTRY *QuestionLink;\r
5694 FORM_BROWSER_FORM *Form;\r
5695 FORM_BROWSER_STATEMENT *Question;\r
892eccc8
ED
5696\r
5697 //\r
5698 // For each form in one formset.\r
5699 //\r
5700 Link = GetFirstNode (&NewFormSet->FormListHead);\r
5701 while (!IsNull (&NewFormSet->FormListHead, Link)) {\r
5702 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
5703 Link = GetNextNode (&NewFormSet->FormListHead, Link);\r
5704\r
5705 //\r
5706 // for each question in one form.\r
5707 //\r
5708 QuestionLink = GetFirstNode (&Form->StatementListHead);\r
5709 while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r
1436aea4 5710 Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
892eccc8
ED
5711 QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
5712\r
5713 if (Question->QuestionId == OldQuestion->QuestionId) {\r
5714 Question->ValueChanged = TRUE;\r
5715 return;\r
5716 }\r
5717 }\r
5718 }\r
5719}\r
5720\r
5721/**\r
5722 Get Value changed status from old formset.\r
5723\r
5724 @param NewFormSet FormSet data structure.\r
5725 @param OldFormSet FormSet data structure.\r
5726\r
5727**/\r
5728VOID\r
5729SyncStatusForFormSet (\r
1436aea4
MK
5730 IN OUT FORM_BROWSER_FORMSET *NewFormSet,\r
5731 IN FORM_BROWSER_FORMSET *OldFormSet\r
892eccc8
ED
5732 )\r
5733{\r
1436aea4
MK
5734 LIST_ENTRY *Link;\r
5735 LIST_ENTRY *QuestionLink;\r
5736 FORM_BROWSER_FORM *Form;\r
5737 FORM_BROWSER_STATEMENT *Question;\r
892eccc8
ED
5738\r
5739 //\r
5740 // For each form in one formset.\r
5741 //\r
5742 Link = GetFirstNode (&OldFormSet->FormListHead);\r
5743 while (!IsNull (&OldFormSet->FormListHead, Link)) {\r
5744 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
5745 Link = GetNextNode (&OldFormSet->FormListHead, Link);\r
5746\r
5747 //\r
5748 // for each question in one form.\r
5749 //\r
5750 QuestionLink = GetFirstNode (&Form->StatementListHead);\r
5751 while (!IsNull (&Form->StatementListHead, QuestionLink)) {\r
1436aea4 5752 Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);\r
892eccc8
ED
5753 QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);\r
5754\r
5755 if (!Question->ValueChanged) {\r
5756 continue;\r
5757 }\r
5758\r
5759 //\r
5760 // Find the same question in new formset and update the value changed flag.\r
5761 //\r
5762 SyncStatusForQuestion (NewFormSet, Question);\r
5763 }\r
5764 }\r
5765}\r
5766\r
7936fb6a 5767/**\r
5768 Get current setting of Questions.\r
5769\r
5770 @param FormSet FormSet data structure.\r
5771\r
7936fb6a 5772**/\r
7c6c064c 5773VOID\r
7936fb6a 5774InitializeCurrentSetting (\r
1436aea4 5775 IN OUT FORM_BROWSER_FORMSET *FormSet\r
7936fb6a 5776 )\r
5777{\r
1436aea4
MK
5778 LIST_ENTRY *Link;\r
5779 FORMSET_STORAGE *Storage;\r
5780 FORM_BROWSER_FORMSET *OldFormSet;\r
7936fb6a 5781\r
6e74560f
ED
5782 //\r
5783 // Try to find pre FormSet in the maintain backup list.\r
5784 // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.\r
5785 //\r
5786 OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);\r
5787 if (OldFormSet != NULL) {\r
892eccc8 5788 SyncStatusForFormSet (FormSet, OldFormSet);\r
6e74560f
ED
5789 RemoveEntryList (&OldFormSet->Link);\r
5790 DestroyFormSet (OldFormSet);\r
5791 }\r
1436aea4 5792\r
6e74560f
ED
5793 InsertTailList (&gBrowserFormSetList, &FormSet->Link);\r
5794\r
1deb5cab
ED
5795 //\r
5796 // Extract default from IFR binary for no storage questions.\r
d1102dba 5797 //\r
787fc2a6 5798 ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForNoStorage, NULL, TRUE, FALSE);\r
1deb5cab 5799\r
7936fb6a 5800 //\r
5801 // Request current settings from Configuration Driver\r
5802 //\r
5803 Link = GetFirstNode (&FormSet->StorageListHead);\r
5804 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
5805 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
5806\r
7c6c064c 5807 LoadStorage (FormSet, Storage);\r
7936fb6a 5808\r
7936fb6a 5809 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
5810 }\r
7936fb6a 5811}\r
5812\r
7936fb6a 5813/**\r
5814 Fetch the Ifr binary data of a FormSet.\r
5815\r
5816 @param Handle PackageList Handle\r
f5006bd9 5817 @param FormSetGuid On input, GUID or class GUID of a formset. If not\r
5818 specified (NULL or zero GUID), take the first\r
5819 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID\r
5820 found in package list.\r
5821 On output, GUID of the formset found(if not NULL).\r
7936fb6a 5822 @param BinaryLength The length of the FormSet IFR binary.\r
5823 @param BinaryData The buffer designed to receive the FormSet.\r
5824\r
5825 @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
5826 BufferLength was updated.\r
5827 @retval EFI_INVALID_PARAMETER The handle is unknown.\r
5828 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
5829 be found with the requested FormId.\r
5830\r
5831**/\r
5832EFI_STATUS\r
5833GetIfrBinaryData (\r
1436aea4
MK
5834 IN EFI_HII_HANDLE Handle,\r
5835 IN OUT EFI_GUID *FormSetGuid,\r
5836 OUT UINTN *BinaryLength,\r
5837 OUT UINT8 **BinaryData\r
7936fb6a 5838 )\r
5839{\r
5840 EFI_STATUS Status;\r
5841 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
5842 UINTN BufferSize;\r
5843 UINT8 *Package;\r
5844 UINT8 *OpCodeData;\r
5845 UINT32 Offset;\r
5846 UINT32 Offset2;\r
7936fb6a 5847 UINT32 PackageListLength;\r
5848 EFI_HII_PACKAGE_HEADER PackageHeader;\r
0a1147ed
LG
5849 UINT8 Index;\r
5850 UINT8 NumberOfClassGuid;\r
f5006bd9 5851 BOOLEAN ClassGuidMatch;\r
0a1147ed 5852 EFI_GUID *ClassGuid;\r
f5006bd9 5853 EFI_GUID *ComparingGuid;\r
7936fb6a 5854\r
5855 OpCodeData = NULL;\r
1436aea4 5856 Package = NULL;\r
0c66bc76 5857 ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));\r
7936fb6a 5858\r
5859 //\r
f5006bd9 5860 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list\r
7936fb6a 5861 //\r
48a9d5f7
LG
5862 if (FormSetGuid == NULL) {\r
5863 ComparingGuid = &gZeroGuid;\r
7936fb6a 5864 } else {\r
f5006bd9 5865 ComparingGuid = FormSetGuid;\r
7936fb6a 5866 }\r
5867\r
5868 //\r
5869 // Get HII PackageList\r
5870 //\r
1436aea4 5871 BufferSize = 0;\r
7936fb6a 5872 HiiPackageList = NULL;\r
1436aea4 5873 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
7936fb6a 5874 if (Status == EFI_BUFFER_TOO_SMALL) {\r
5875 HiiPackageList = AllocatePool (BufferSize);\r
5876 ASSERT (HiiPackageList != NULL);\r
5877\r
5878 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
5879 }\r
1436aea4 5880\r
7936fb6a 5881 if (EFI_ERROR (Status)) {\r
5882 return Status;\r
5883 }\r
1436aea4 5884\r
db0bd81c 5885 ASSERT (HiiPackageList != NULL);\r
d66e6c16 5886\r
7936fb6a 5887 //\r
5888 // Get Form package from this HII package List\r
5889 //\r
1436aea4 5890 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
7936fb6a 5891 Offset2 = 0;\r
5892 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
5893\r
f5006bd9 5894 ClassGuidMatch = FALSE;\r
7936fb6a 5895 while (Offset < PackageListLength) {\r
1436aea4 5896 Package = ((UINT8 *)HiiPackageList) + Offset;\r
7936fb6a 5897 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
5898\r
8d00a0f1 5899 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
7936fb6a 5900 //\r
5901 // Search FormSet in this Form Package\r
5902 //\r
5903 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
5904 while (Offset2 < PackageHeader.Length) {\r
5905 OpCodeData = Package + Offset2;\r
5906\r
1436aea4 5907 if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
7936fb6a 5908 //\r
f5006bd9 5909 // Try to compare against formset GUID\r
7936fb6a 5910 //\r
7d325f93 5911 if (IsZeroGuid (ComparingGuid) ||\r
1436aea4
MK
5912 CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER))))\r
5913 {\r
f5006bd9 5914 break;\r
7936fb6a 5915 }\r
5916\r
1436aea4 5917 if (((EFI_IFR_OP_HEADER *)OpCodeData)->Length > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
d228526f
LG
5918 //\r
5919 // Try to compare against formset class GUID\r
5920 //\r
1436aea4
MK
5921 NumberOfClassGuid = (UINT8)(((EFI_IFR_FORM_SET *)OpCodeData)->Flags & 0x3);\r
5922 ClassGuid = (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_FORM_SET));\r
d228526f
LG
5923 for (Index = 0; Index < NumberOfClassGuid; Index++) {\r
5924 if (CompareGuid (ComparingGuid, ClassGuid + Index)) {\r
5925 ClassGuidMatch = TRUE;\r
5926 break;\r
5927 }\r
5928 }\r
1436aea4 5929\r
d228526f 5930 if (ClassGuidMatch) {\r
f5006bd9 5931 break;\r
5932 }\r
d228526f
LG
5933 } else if (ComparingGuid == &gEfiHiiPlatformSetupFormsetGuid) {\r
5934 ClassGuidMatch = TRUE;\r
7936fb6a 5935 break;\r
5936 }\r
5937 }\r
5938\r
1436aea4 5939 Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;\r
7936fb6a 5940 }\r
5941\r
5942 if (Offset2 < PackageHeader.Length) {\r
5943 //\r
5944 // Target formset found\r
5945 //\r
5946 break;\r
5947 }\r
5948 }\r
5949\r
5950 Offset += PackageHeader.Length;\r
5951 }\r
5952\r
5953 if (Offset >= PackageListLength) {\r
5954 //\r
5955 // Form package not found in this Package List\r
5956 //\r
f4113e1f 5957 FreePool (HiiPackageList);\r
7936fb6a 5958 return EFI_NOT_FOUND;\r
5959 }\r
5960\r
48a9d5f7 5961 if (FormSetGuid != NULL) {\r
7936fb6a 5962 //\r
f5006bd9 5963 // Return the FormSet GUID\r
7936fb6a 5964 //\r
1436aea4 5965 CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *)OpCodeData)->Guid, sizeof (EFI_GUID));\r
7936fb6a 5966 }\r
5967\r
5968 //\r
5969 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
5970 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
5971 // of the Form Package.\r
5972 //\r
5973 *BinaryLength = PackageHeader.Length - Offset2;\r
1436aea4 5974 *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
7936fb6a 5975\r
f4113e1f 5976 FreePool (HiiPackageList);\r
7936fb6a 5977\r
5978 if (*BinaryData == NULL) {\r
5979 return EFI_OUT_OF_RESOURCES;\r
5980 }\r
5981\r
5982 return EFI_SUCCESS;\r
5983}\r
5984\r
7936fb6a 5985/**\r
5986 Initialize the internal data structure of a FormSet.\r
5987\r
5988 @param Handle PackageList Handle\r
f5006bd9 5989 @param FormSetGuid On input, GUID or class GUID of a formset. If not\r
5990 specified (NULL or zero GUID), take the first\r
5991 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID\r
5992 found in package list.\r
5993 On output, GUID of the formset found(if not NULL).\r
7936fb6a 5994 @param FormSet FormSet data structure.\r
5995\r
5996 @retval EFI_SUCCESS The function completed successfully.\r
5997 @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
5998\r
5999**/\r
6000EFI_STATUS\r
6001InitializeFormSet (\r
1436aea4
MK
6002 IN EFI_HII_HANDLE Handle,\r
6003 IN OUT EFI_GUID *FormSetGuid,\r
6004 OUT FORM_BROWSER_FORMSET *FormSet\r
7936fb6a 6005 )\r
6006{\r
1436aea4
MK
6007 EFI_STATUS Status;\r
6008 EFI_HANDLE DriverHandle;\r
7936fb6a 6009\r
6010 Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
6011 if (EFI_ERROR (Status)) {\r
6012 return Status;\r
6013 }\r
6014\r
48a9d5f7 6015 FormSet->Signature = FORM_BROWSER_FORMSET_SIGNATURE;\r
7936fb6a 6016 FormSet->HiiHandle = Handle;\r
6017 CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
7c6c064c 6018 FormSet->QuestionInited = FALSE;\r
7936fb6a 6019\r
6020 //\r
6021 // Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
6022 //\r
6023 Status = mHiiDatabase->GetPackageListHandle (mHiiDatabase, Handle, &DriverHandle);\r
6024 if (EFI_ERROR (Status)) {\r
6025 return Status;\r
6026 }\r
1436aea4 6027\r
7936fb6a 6028 FormSet->DriverHandle = DriverHandle;\r
1436aea4
MK
6029 Status = gBS->HandleProtocol (\r
6030 DriverHandle,\r
6031 &gEfiHiiConfigAccessProtocolGuid,\r
6032 (VOID **)&FormSet->ConfigAccess\r
6033 );\r
7936fb6a 6034 if (EFI_ERROR (Status)) {\r
6035 //\r
6036 // Configuration Driver don't attach ConfigAccess protocol to its HII package\r
6037 // list, then there will be no configuration action required\r
6038 //\r
6039 FormSet->ConfigAccess = NULL;\r
6040 }\r
6041\r
6042 //\r
6043 // Parse the IFR binary OpCodes\r
6044 //\r
6045 Status = ParseOpCodes (FormSet);\r
25361615 6046\r
7c6c064c 6047 return Status;\r
7936fb6a 6048}\r
ce6d12cc 6049\r
ce6d12cc 6050/**\r
d1102dba 6051 Save globals used by previous call to SendForm(). SendForm() may be called from\r
ce6d12cc 6052 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.\r
6053 So, save globals of previous call to SendForm() and restore them upon exit.\r
6054\r
6055**/\r
6056VOID\r
6057SaveBrowserContext (\r
6058 VOID\r
6059 )\r
6060{\r
1436aea4
MK
6061 BROWSER_CONTEXT *Context;\r
6062 FORM_ENTRY_INFO *MenuList;\r
6063 FORM_BROWSER_FORMSET *FormSet;\r
ce6d12cc 6064\r
6065 gBrowserContextCount++;\r
6066 if (gBrowserContextCount == 1) {\r
6067 //\r
6068 // This is not reentry of SendForm(), no context to save\r
6069 //\r
6070 return;\r
6071 }\r
6072\r
6073 Context = AllocatePool (sizeof (BROWSER_CONTEXT));\r
6074 ASSERT (Context != NULL);\r
6075\r
6076 Context->Signature = BROWSER_CONTEXT_SIGNATURE;\r
6077\r
6078 //\r
6079 // Save FormBrowser context\r
6080 //\r
1436aea4
MK
6081 Context->Selection = gCurrentSelection;\r
6082 Context->ResetRequired = gResetRequiredFormLevel;\r
6083 Context->FlagReconnect = gFlagReconnect;\r
6084 Context->CallbackReconnect = gCallbackReconnect;\r
6085 Context->ExitRequired = gExitRequired;\r
6086 Context->HiiHandle = mCurrentHiiHandle;\r
6087 Context->FormId = mCurrentFormId;\r
5a9f73bf 6088 CopyGuid (&Context->FormSetGuid, &mCurrentFormSetGuid);\r
1436aea4
MK
6089 Context->SystemLevelFormSet = mSystemLevelFormSet;\r
6090 Context->CurFakeQestId = mCurFakeQestId;\r
f4c3c923 6091 Context->HiiPackageListUpdated = mHiiPackageListUpdated;\r
1436aea4 6092 Context->FinishRetrieveCall = mFinishRetrieveCall;\r
7c6c064c
ED
6093\r
6094 //\r
6095 // Save the menu history data.\r
6096 //\r
1436aea4 6097 InitializeListHead (&Context->FormHistoryList);\r
7c6c064c
ED
6098 while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {\r
6099 MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);\r
6100 RemoveEntryList (&MenuList->Link);\r
6101\r
1436aea4 6102 InsertTailList (&Context->FormHistoryList, &MenuList->Link);\r
7c6c064c 6103 }\r
ce6d12cc 6104\r
b6f61255
ED
6105 //\r
6106 // Save formset list.\r
6107 //\r
1436aea4 6108 InitializeListHead (&Context->FormSetList);\r
b6f61255
ED
6109 while (!IsListEmpty (&gBrowserFormSetList)) {\r
6110 FormSet = FORM_BROWSER_FORMSET_FROM_LINK (gBrowserFormSetList.ForwardLink);\r
6111 RemoveEntryList (&FormSet->Link);\r
6112\r
1436aea4 6113 InsertTailList (&Context->FormSetList, &FormSet->Link);\r
b6f61255
ED
6114 }\r
6115\r
ce6d12cc 6116 //\r
6117 // Insert to FormBrowser context list\r
6118 //\r
6119 InsertHeadList (&gBrowserContextList, &Context->Link);\r
6120}\r
6121\r
ce6d12cc 6122/**\r
6123 Restore globals used by previous call to SendForm().\r
6124\r
6125**/\r
6126VOID\r
6127RestoreBrowserContext (\r
6128 VOID\r
6129 )\r
6130{\r
1436aea4
MK
6131 LIST_ENTRY *Link;\r
6132 BROWSER_CONTEXT *Context;\r
6133 FORM_ENTRY_INFO *MenuList;\r
6134 FORM_BROWSER_FORMSET *FormSet;\r
ce6d12cc 6135\r
6136 ASSERT (gBrowserContextCount != 0);\r
6137 gBrowserContextCount--;\r
6138 if (gBrowserContextCount == 0) {\r
6139 //\r
6140 // This is not reentry of SendForm(), no context to restore\r
6141 //\r
6142 return;\r
6143 }\r
6144\r
6145 ASSERT (!IsListEmpty (&gBrowserContextList));\r
6146\r
1436aea4 6147 Link = GetFirstNode (&gBrowserContextList);\r
ce6d12cc 6148 Context = BROWSER_CONTEXT_FROM_LINK (Link);\r
6149\r
6150 //\r
6151 // Restore FormBrowser context\r
6152 //\r
1436aea4 6153 gCurrentSelection = Context->Selection;\r
b2dcae4c 6154 gResetRequiredFormLevel = Context->ResetRequired;\r
1436aea4
MK
6155 gFlagReconnect = Context->FlagReconnect;\r
6156 gCallbackReconnect = Context->CallbackReconnect;\r
6157 gExitRequired = Context->ExitRequired;\r
6158 mCurrentHiiHandle = Context->HiiHandle;\r
6159 mCurrentFormId = Context->FormId;\r
5a9f73bf 6160 CopyGuid (&mCurrentFormSetGuid, &Context->FormSetGuid);\r
1436aea4
MK
6161 mSystemLevelFormSet = Context->SystemLevelFormSet;\r
6162 mCurFakeQestId = Context->CurFakeQestId;\r
f4c3c923 6163 mHiiPackageListUpdated = Context->HiiPackageListUpdated;\r
1436aea4 6164 mFinishRetrieveCall = Context->FinishRetrieveCall;\r
7c6c064c
ED
6165\r
6166 //\r
6167 // Restore the menu history data.\r
6168 //\r
6169 while (!IsListEmpty (&Context->FormHistoryList)) {\r
6170 MenuList = FORM_ENTRY_INFO_FROM_LINK (Context->FormHistoryList.ForwardLink);\r
6171 RemoveEntryList (&MenuList->Link);\r
6172\r
1436aea4 6173 InsertTailList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);\r
7c6c064c 6174 }\r
ce6d12cc 6175\r
b6f61255
ED
6176 //\r
6177 // Restore the Formset data.\r
6178 //\r
6179 while (!IsListEmpty (&Context->FormSetList)) {\r
6180 FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Context->FormSetList.ForwardLink);\r
6181 RemoveEntryList (&FormSet->Link);\r
6182\r
1436aea4 6183 InsertTailList (&gBrowserFormSetList, &FormSet->Link);\r
b6f61255
ED
6184 }\r
6185\r
ce6d12cc 6186 //\r
6187 // Remove from FormBrowser context list\r
6188 //\r
6189 RemoveEntryList (&Context->Link);\r
6190 gBS->FreePool (Context);\r
6191}\r
48a9d5f7
LG
6192\r
6193/**\r
6194 Find the matched FormSet context in the backup maintain list based on HiiHandle.\r
d1102dba 6195\r
48a9d5f7 6196 @param Handle The Hii Handle.\r
d1102dba 6197\r
48a9d5f7
LG
6198 @return the found FormSet context. If no found, NULL will return.\r
6199\r
6200**/\r
d1102dba 6201FORM_BROWSER_FORMSET *\r
48a9d5f7 6202GetFormSetFromHiiHandle (\r
1436aea4 6203 EFI_HII_HANDLE Handle\r
48a9d5f7
LG
6204 )\r
6205{\r
1436aea4
MK
6206 LIST_ENTRY *Link;\r
6207 FORM_BROWSER_FORMSET *FormSet;\r
48a9d5f7
LG
6208\r
6209 Link = GetFirstNode (&gBrowserFormSetList);\r
6210 while (!IsNull (&gBrowserFormSetList, Link)) {\r
6211 FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
1436aea4
MK
6212 Link = GetNextNode (&gBrowserFormSetList, Link);\r
6213 if (!ValidateFormSet (FormSet)) {\r
938baa1f
ED
6214 continue;\r
6215 }\r
1436aea4 6216\r
48a9d5f7
LG
6217 if (FormSet->HiiHandle == Handle) {\r
6218 return FormSet;\r
6219 }\r
48a9d5f7 6220 }\r
d1102dba 6221\r
48a9d5f7
LG
6222 return NULL;\r
6223}\r
6224\r
6225/**\r
6226 Check whether the input HII handle is the FormSet that is being used.\r
d1102dba 6227\r
48a9d5f7 6228 @param Handle The Hii Handle.\r
d1102dba 6229\r
48a9d5f7
LG
6230 @retval TRUE HII handle is being used.\r
6231 @retval FALSE HII handle is not being used.\r
6232\r
6233**/\r
6234BOOLEAN\r
6235IsHiiHandleInBrowserContext (\r
1436aea4 6236 EFI_HII_HANDLE Handle\r
48a9d5f7
LG
6237 )\r
6238{\r
6239 LIST_ENTRY *Link;\r
6240 BROWSER_CONTEXT *Context;\r
6241\r
6242 //\r
6243 // HiiHandle is Current FormSet.\r
6244 //\r
7c6c064c 6245 if (mCurrentHiiHandle == Handle) {\r
48a9d5f7
LG
6246 return TRUE;\r
6247 }\r
6248\r
6249 //\r
6250 // Check whether HiiHandle is in BrowserContext.\r
6251 //\r
6252 Link = GetFirstNode (&gBrowserContextList);\r
6253 while (!IsNull (&gBrowserContextList, Link)) {\r
6254 Context = BROWSER_CONTEXT_FROM_LINK (Link);\r
7c6c064c 6255 if (Context->HiiHandle == Handle) {\r
48a9d5f7
LG
6256 //\r
6257 // HiiHandle is in BrowserContext\r
6258 //\r
6259 return TRUE;\r
6260 }\r
1436aea4 6261\r
48a9d5f7
LG
6262 Link = GetNextNode (&gBrowserContextList, Link);\r
6263 }\r
d1102dba 6264\r
48a9d5f7
LG
6265 return FALSE;\r
6266}\r
6267\r
7c6c064c 6268/**\r
d1102dba 6269 Perform Password check.\r
7c6c064c 6270 Passwork may be encrypted by driver that requires the specific check.\r
d1102dba 6271\r
7c6c064c
ED
6272 @param Form Form where Password Statement is in.\r
6273 @param Statement Password statement\r
6274 @param PasswordString Password string to be checked. It may be NULL.\r
6275 NULL means to restore password.\r
6276 "" string can be used to checked whether old password does exist.\r
d1102dba 6277\r
7c6c064c
ED
6278 @return Status Status of Password check.\r
6279**/\r
6280EFI_STATUS\r
6281EFIAPI\r
6282PasswordCheck (\r
1436aea4
MK
6283 IN FORM_DISPLAY_ENGINE_FORM *Form,\r
6284 IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
6285 IN EFI_STRING PasswordString OPTIONAL\r
7c6c064c
ED
6286 )\r
6287{\r
6288 EFI_STATUS Status;\r
6289 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
6290 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
6291 EFI_IFR_TYPE_VALUE IfrTypeValue;\r
6292 FORM_BROWSER_STATEMENT *Question;\r
6293\r
6294 ConfigAccess = gCurrentSelection->FormSet->ConfigAccess;\r
1436aea4 6295 Question = GetBrowserStatement (Statement);\r
7c6c064c
ED
6296 ASSERT (Question != NULL);\r
6297\r
6298 if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) {\r
6299 if (ConfigAccess == NULL) {\r
6300 return EFI_UNSUPPORTED;\r
6301 }\r
6302 } else {\r
27582c41 6303 //\r
9e2462b8 6304 // If a password doesn't have the CALLBACK flag, browser will not handle it.\r
27582c41 6305 //\r
9e2462b8 6306 return EFI_UNSUPPORTED;\r
7c6c064c 6307 }\r
d1102dba 6308\r
7c6c064c
ED
6309 //\r
6310 // Prepare password string in HII database\r
6311 //\r
6312 if (PasswordString != NULL) {\r
6313 IfrTypeValue.string = NewString (PasswordString, gCurrentSelection->FormSet->HiiHandle);\r
6314 } else {\r
6315 IfrTypeValue.string = 0;\r
6316 }\r
6317\r
6318 //\r
6319 // Send password to Configuration Driver for validation\r
6320 //\r
6321 Status = ConfigAccess->Callback (\r
6322 ConfigAccess,\r
6323 EFI_BROWSER_ACTION_CHANGING,\r
6324 Question->QuestionId,\r
6325 Question->HiiValue.Type,\r
6326 &IfrTypeValue,\r
6327 &ActionRequest\r
6328 );\r
6329\r
6330 //\r
6331 // Remove password string from HII database\r
6332 //\r
6333 if (PasswordString != NULL) {\r
6334 DeleteString (IfrTypeValue.string, gCurrentSelection->FormSet->HiiHandle);\r
6335 }\r
6336\r
6337 return Status;\r
6338}\r
6339\r
48a9d5f7
LG
6340/**\r
6341 Find the registered HotKey based on KeyData.\r
d1102dba 6342\r
48a9d5f7
LG
6343 @param[in] KeyData A pointer to a buffer that describes the keystroke\r
6344 information for the hot key.\r
6345\r
6346 @return The registered HotKey context. If no found, NULL will return.\r
6347**/\r
6348BROWSER_HOT_KEY *\r
6349GetHotKeyFromRegisterList (\r
1436aea4 6350 IN EFI_INPUT_KEY *KeyData\r
48a9d5f7
LG
6351 )\r
6352{\r
6353 LIST_ENTRY *Link;\r
6354 BROWSER_HOT_KEY *HotKey;\r
6355\r
6356 Link = GetFirstNode (&gBrowserHotKeyList);\r
6357 while (!IsNull (&gBrowserHotKeyList, Link)) {\r
6358 HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
6359 if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {\r
6360 return HotKey;\r
6361 }\r
1436aea4 6362\r
48a9d5f7
LG
6363 Link = GetNextNode (&gBrowserHotKeyList, Link);\r
6364 }\r
d1102dba 6365\r
48a9d5f7
LG
6366 return NULL;\r
6367}\r
6368\r
6369/**\r
6370 Configure what scope the hot key will impact.\r
6371 All hot keys have the same scope. The mixed hot keys with the different level are not supported.\r
6372 If no scope is set, the default scope will be FormSet level.\r
6373 After all registered hot keys are removed, previous Scope can reset to another level.\r
d1102dba
LG
6374\r
6375 @param[in] Scope Scope level to be set.\r
6376\r
48a9d5f7 6377 @retval EFI_SUCCESS Scope is set correctly.\r
d1102dba 6378 @retval EFI_INVALID_PARAMETER Scope is not the valid value specified in BROWSER_SETTING_SCOPE.\r
48a9d5f7
LG
6379 @retval EFI_UNSPPORTED Scope level is different from current one that the registered hot keys have.\r
6380\r
6381**/\r
6382EFI_STATUS\r
6383EFIAPI\r
6384SetScope (\r
1436aea4 6385 IN BROWSER_SETTING_SCOPE Scope\r
48a9d5f7
LG
6386 )\r
6387{\r
6388 if (Scope >= MaxLevel) {\r
6389 return EFI_INVALID_PARAMETER;\r
6390 }\r
7c6c064c 6391\r
48a9d5f7
LG
6392 //\r
6393 // When no hot key registered in system or on the first setting,\r
6394 // Scope can be set.\r
6395 //\r
6396 if (mBrowserScopeFirstSet || IsListEmpty (&gBrowserHotKeyList)) {\r
6397 gBrowserSettingScope = Scope;\r
6398 mBrowserScopeFirstSet = FALSE;\r
6399 } else if (Scope != gBrowserSettingScope) {\r
6400 return EFI_UNSUPPORTED;\r
6401 }\r
6402\r
6403 return EFI_SUCCESS;\r
6404}\r
6405\r
6406/**\r
6407 Register the hot key with its browser action, or unregistered the hot key.\r
6408 Only support hot key that is not printable character (control key, function key, etc.).\r
6409 If the action value is zero, the hot key will be unregistered if it has been registered.\r
6410 If the same hot key has been registered, the new action and help string will override the previous ones.\r
d1102dba 6411\r
48a9d5f7 6412 @param[in] KeyData A pointer to a buffer that describes the keystroke\r
d1102dba 6413 information for the hot key. Its type is EFI_INPUT_KEY to\r
48a9d5f7 6414 be supported by all ConsoleIn devices.\r
d1102dba 6415 @param[in] Action Action value that describes what action will be trigged when the hot key is pressed.\r
48a9d5f7
LG
6416 @param[in] DefaultId Specifies the type of defaults to retrieve, which is only for DEFAULT action.\r
6417 @param[in] HelpString Help string that describes the hot key information.\r
6418 Its value may be NULL for the unregistered hot key.\r
d1102dba 6419\r
48a9d5f7
LG
6420 @retval EFI_SUCCESS Hot key is registered or unregistered.\r
6421 @retval EFI_INVALID_PARAMETER KeyData is NULL or HelpString is NULL on register.\r
6422 @retval EFI_NOT_FOUND KeyData is not found to be unregistered.\r
6423 @retval EFI_UNSUPPORTED Key represents a printable character. It is conflicted with Browser.\r
291422d7 6424 @retval EFI_ALREADY_STARTED Key already been registered for one hot key.\r
48a9d5f7
LG
6425**/\r
6426EFI_STATUS\r
6427EFIAPI\r
6428RegisterHotKey (\r
1436aea4
MK
6429 IN EFI_INPUT_KEY *KeyData,\r
6430 IN UINT32 Action,\r
6431 IN UINT16 DefaultId,\r
6432 IN EFI_STRING HelpString OPTIONAL\r
48a9d5f7
LG
6433 )\r
6434{\r
6435 BROWSER_HOT_KEY *HotKey;\r
6436\r
6437 //\r
6438 // Check input parameters.\r
6439 //\r
1436aea4
MK
6440 if ((KeyData == NULL) || (KeyData->UnicodeChar != CHAR_NULL) ||\r
6441 ((Action != BROWSER_ACTION_UNREGISTER) && (HelpString == NULL)))\r
6442 {\r
48a9d5f7
LG
6443 return EFI_INVALID_PARAMETER;\r
6444 }\r
6445\r
6446 //\r
6447 // Check whether the input KeyData is in BrowserHotKeyList.\r
6448 //\r
6449 HotKey = GetHotKeyFromRegisterList (KeyData);\r
d1102dba 6450\r
48a9d5f7
LG
6451 //\r
6452 // Unregister HotKey\r
6453 //\r
6454 if (Action == BROWSER_ACTION_UNREGISTER) {\r
6455 if (HotKey != NULL) {\r
6456 //\r
d1102dba 6457 // The registered HotKey is found.\r
48a9d5f7
LG
6458 // Remove it from List, and free its resource.\r
6459 //\r
6460 RemoveEntryList (&HotKey->Link);\r
6461 FreePool (HotKey->KeyData);\r
6462 FreePool (HotKey->HelpString);\r
6463 return EFI_SUCCESS;\r
6464 } else {\r
6465 //\r
d1102dba 6466 // The registered HotKey is not found.\r
48a9d5f7
LG
6467 //\r
6468 return EFI_NOT_FOUND;\r
6469 }\r
6470 }\r
291422d7
ED
6471\r
6472 if (HotKey != NULL) {\r
6473 return EFI_ALREADY_STARTED;\r
6474 }\r
6475\r
48a9d5f7 6476 //\r
291422d7 6477 // Create new Key, and add it into List.\r
48a9d5f7 6478 //\r
291422d7
ED
6479 HotKey = AllocateZeroPool (sizeof (BROWSER_HOT_KEY));\r
6480 ASSERT (HotKey != NULL);\r
6481 HotKey->Signature = BROWSER_HOT_KEY_SIGNATURE;\r
6482 HotKey->KeyData = AllocateCopyPool (sizeof (EFI_INPUT_KEY), KeyData);\r
6483 InsertTailList (&gBrowserHotKeyList, &HotKey->Link);\r
48a9d5f7
LG
6484\r
6485 //\r
6486 // Fill HotKey information.\r
6487 //\r
1436aea4
MK
6488 HotKey->Action = Action;\r
6489 HotKey->DefaultId = DefaultId;\r
48a9d5f7
LG
6490 if (HotKey->HelpString != NULL) {\r
6491 FreePool (HotKey->HelpString);\r
6492 }\r
1436aea4 6493\r
48a9d5f7
LG
6494 HotKey->HelpString = AllocateCopyPool (StrSize (HelpString), HelpString);\r
6495\r
6496 return EFI_SUCCESS;\r
6497}\r
6498\r
6499/**\r
d1102dba
LG
6500 Register Exit handler function.\r
6501 When more than one handler function is registered, the latter one will override the previous one.\r
6502 When NULL handler is specified, the previous Exit handler will be unregistered.\r
6503\r
6504 @param[in] Handler Pointer to handler function.\r
48a9d5f7
LG
6505\r
6506**/\r
6507VOID\r
6508EFIAPI\r
6509RegiserExitHandler (\r
1436aea4 6510 IN EXIT_HANDLER Handler\r
48a9d5f7
LG
6511 )\r
6512{\r
6513 ExitHandlerFunction = Handler;\r
6514 return;\r
6515}\r
6516\r
7c6c064c
ED
6517/**\r
6518 Check whether the browser data has been modified.\r
6519\r
6520 @retval TRUE Browser data is modified.\r
6521 @retval FALSE No browser data is modified.\r
6522\r
6523**/\r
6524BOOLEAN\r
6525EFIAPI\r
6526IsBrowserDataModified (\r
6527 VOID\r
6528 )\r
6529{\r
1436aea4
MK
6530 LIST_ENTRY *Link;\r
6531 FORM_BROWSER_FORMSET *FormSet;\r
7c6c064c 6532\r
7c6c064c
ED
6533 switch (gBrowserSettingScope) {\r
6534 case FormLevel:\r
27bace9b
ED
6535 if (gCurrentSelection == NULL) {\r
6536 return FALSE;\r
6537 }\r
1436aea4 6538\r
7c6c064c
ED
6539 return IsNvUpdateRequiredForForm (gCurrentSelection->Form);\r
6540\r
6541 case FormSetLevel:\r
27bace9b
ED
6542 if (gCurrentSelection == NULL) {\r
6543 return FALSE;\r
6544 }\r
1436aea4 6545\r
7c6c064c
ED
6546 return IsNvUpdateRequiredForFormSet (gCurrentSelection->FormSet);\r
6547\r
6548 case SystemLevel:\r
6549 Link = GetFirstNode (&gBrowserFormSetList);\r
6550 while (!IsNull (&gBrowserFormSetList, Link)) {\r
6551 FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
1436aea4 6552 if (!ValidateFormSet (FormSet)) {\r
27bace9b
ED
6553 continue;\r
6554 }\r
6555\r
7c6c064c
ED
6556 if (IsNvUpdateRequiredForFormSet (FormSet)) {\r
6557 return TRUE;\r
6558 }\r
1436aea4 6559\r
7c6c064c
ED
6560 Link = GetNextNode (&gBrowserFormSetList, Link);\r
6561 }\r
1436aea4 6562\r
7c6c064c
ED
6563 return FALSE;\r
6564\r
6565 default:\r
6566 return FALSE;\r
6567 }\r
6568}\r
6569\r
6570/**\r
6571 Execute the action requested by the Action parameter.\r
6572\r
6573 @param[in] Action Execute the request action.\r
6574 @param[in] DefaultId The default Id info when need to load default value. Only used when Action is BROWSER_ACTION_DEFAULT.\r
6575\r
6576 @retval EFI_SUCCESS Execute the request action succss.\r
6577 @retval EFI_INVALID_PARAMETER The input action value is invalid.\r
6578\r
6579**/\r
d1102dba 6580EFI_STATUS\r
7c6c064c
ED
6581EFIAPI\r
6582ExecuteAction (\r
1436aea4
MK
6583 IN UINT32 Action,\r
6584 IN UINT16 DefaultId\r
7c6c064c
ED
6585 )\r
6586{\r
1436aea4
MK
6587 EFI_STATUS Status;\r
6588 FORM_BROWSER_FORMSET *FormSet;\r
6589 FORM_BROWSER_FORM *Form;\r
7c6c064c 6590\r
1436aea4 6591 if ((gBrowserSettingScope < SystemLevel) && (gCurrentSelection == NULL)) {\r
7c6c064c
ED
6592 return EFI_NOT_READY;\r
6593 }\r
6594\r
27bace9b
ED
6595 Status = EFI_SUCCESS;\r
6596 FormSet = NULL;\r
6597 Form = NULL;\r
6598 if (gBrowserSettingScope < SystemLevel) {\r
6599 FormSet = gCurrentSelection->FormSet;\r
d1102dba 6600 Form = gCurrentSelection->Form;\r
27bace9b 6601 }\r
7c6c064c
ED
6602\r
6603 //\r
6604 // Executet the discard action.\r
6605 //\r
6606 if ((Action & BROWSER_ACTION_DISCARD) != 0) {\r
27bace9b 6607 Status = DiscardForm (FormSet, Form, gBrowserSettingScope);\r
7c6c064c
ED
6608 if (EFI_ERROR (Status)) {\r
6609 return Status;\r
6610 }\r
6611 }\r
6612\r
6613 //\r
6614 // Executet the difault action.\r
6615 //\r
6616 if ((Action & BROWSER_ACTION_DEFAULT) != 0) {\r
787fc2a6 6617 Status = ExtractDefault (FormSet, Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE, FALSE);\r
7c6c064c
ED
6618 if (EFI_ERROR (Status)) {\r
6619 return Status;\r
6620 }\r
1436aea4 6621\r
892eccc8 6622 UpdateStatementStatus (FormSet, Form, gBrowserSettingScope);\r
7c6c064c
ED
6623 }\r
6624\r
6625 //\r
6626 // Executet the submit action.\r
6627 //\r
6628 if ((Action & BROWSER_ACTION_SUBMIT) != 0) {\r
27bace9b 6629 Status = SubmitForm (FormSet, Form, gBrowserSettingScope);\r
7c6c064c
ED
6630 if (EFI_ERROR (Status)) {\r
6631 return Status;\r
6632 }\r
6633 }\r
6634\r
6635 //\r
6636 // Executet the reset action.\r
6637 //\r
6638 if ((Action & BROWSER_ACTION_RESET) != 0) {\r
1436aea4 6639 gResetRequiredFormLevel = TRUE;\r
b2dcae4c 6640 gResetRequiredSystemLevel = TRUE;\r
7c6c064c
ED
6641 }\r
6642\r
6643 //\r
6644 // Executet the exit action.\r
6645 //\r
6646 if ((Action & BROWSER_ACTION_EXIT) != 0) {\r
27bace9b 6647 DiscardForm (FormSet, Form, gBrowserSettingScope);\r
7c6c064c
ED
6648 if (gBrowserSettingScope == SystemLevel) {\r
6649 if (ExitHandlerFunction != NULL) {\r
6650 ExitHandlerFunction ();\r
6651 }\r
6652 }\r
6653\r
6654 gExitRequired = TRUE;\r
6655 }\r
6656\r
6657 return Status;\r
6658}\r
6659\r
48a9d5f7
LG
6660/**\r
6661 Create reminder to let user to choose save or discard the changed browser data.\r
6662 Caller can use it to actively check the changed browser data.\r
6663\r
6664 @retval BROWSER_NO_CHANGES No browser data is changed.\r
6665 @retval BROWSER_SAVE_CHANGES The changed browser data is saved.\r
6666 @retval BROWSER_DISCARD_CHANGES The changed browser data is discard.\r
27bace9b 6667 @retval BROWSER_KEEP_CURRENT Browser keep current changes.\r
48a9d5f7
LG
6668\r
6669**/\r
6670UINT32\r
6671EFIAPI\r
6672SaveReminder (\r
6673 VOID\r
6674 )\r
6675{\r
1436aea4
MK
6676 LIST_ENTRY *Link;\r
6677 FORM_BROWSER_FORMSET *FormSet;\r
6678 BOOLEAN IsDataChanged;\r
6679 UINT32 DataSavedAction;\r
6680 UINT32 ConfirmRet;\r
6681\r
6682 DataSavedAction = BROWSER_NO_CHANGES;\r
6683 IsDataChanged = FALSE;\r
6684 Link = GetFirstNode (&gBrowserFormSetList);\r
48a9d5f7
LG
6685 while (!IsNull (&gBrowserFormSetList, Link)) {\r
6686 FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
1436aea4
MK
6687 Link = GetNextNode (&gBrowserFormSetList, Link);\r
6688 if (!ValidateFormSet (FormSet)) {\r
938baa1f
ED
6689 continue;\r
6690 }\r
1436aea4 6691\r
7c6c064c 6692 if (IsNvUpdateRequiredForFormSet (FormSet)) {\r
48a9d5f7
LG
6693 IsDataChanged = TRUE;\r
6694 break;\r
6695 }\r
48a9d5f7 6696 }\r
d1102dba 6697\r
48a9d5f7 6698 //\r
d1102dba 6699 // No data is changed. No save is required.\r
48a9d5f7
LG
6700 //\r
6701 if (!IsDataChanged) {\r
6702 return DataSavedAction;\r
6703 }\r
d1102dba 6704\r
48a9d5f7 6705 //\r
d1102dba 6706 // If data is changed, prompt user to save or discard it.\r
48a9d5f7 6707 //\r
48a9d5f7 6708 do {\r
1436aea4 6709 ConfirmRet = (UINT32)mFormDisplay->ConfirmDataChange ();\r
48a9d5f7 6710\r
27bace9b 6711 if (ConfirmRet == BROWSER_ACTION_SUBMIT) {\r
7c6c064c 6712 SubmitForm (NULL, NULL, SystemLevel);\r
27bace9b 6713 DataSavedAction = BROWSER_SAVE_CHANGES;\r
7c6c064c 6714 break;\r
27bace9b 6715 } else if (ConfirmRet == BROWSER_ACTION_DISCARD) {\r
7c6c064c 6716 DiscardForm (NULL, NULL, SystemLevel);\r
27bace9b
ED
6717 DataSavedAction = BROWSER_DISCARD_CHANGES;\r
6718 break;\r
6719 } else if (ConfirmRet == BROWSER_ACTION_NONE) {\r
6720 DataSavedAction = BROWSER_KEEP_CURRENT;\r
7c6c064c
ED
6721 break;\r
6722 }\r
6723 } while (1);\r
48a9d5f7
LG
6724\r
6725 return DataSavedAction;\r
6726}\r
7da62bc0
ED
6727\r
6728/**\r
6729 Check whether the Reset Required for the browser\r
6730\r
6731 @retval TRUE Browser required to reset after exit.\r
6732 @retval FALSE Browser not need to reset after exit.\r
6733\r
6734**/\r
6735BOOLEAN\r
6736EFIAPI\r
6737IsResetRequired (\r
6738 VOID\r
6739 )\r
6740{\r
b2dcae4c 6741 return gResetRequiredSystemLevel;\r
7da62bc0 6742}\r