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