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