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