]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
Change the FormBrowser behavior of "Pressing ESC":
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Setup.c
CommitLineData
7936fb6a 1/** @file\r
2Entry and initialization module for the browser.\r
3\r
d66e6c16 4Copyright (c) 2007 - 2009, Intel Corporation\r
7936fb6a 5All rights reserved. This program and the accompanying materials\r
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
16#include "Ui.h"\r
17\r
18\r
19SETUP_DRIVER_PRIVATE_DATA mPrivateData = {\r
20 SETUP_DRIVER_SIGNATURE,\r
21 NULL,\r
22 {\r
23 SendForm,\r
24 BrowserCallback\r
7936fb6a 25 }\r
26};\r
27\r
28EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;\r
29EFI_HII_STRING_PROTOCOL *mHiiString;\r
30EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;\r
31\r
0a1147ed
LG
32BANNER_DATA *gBannerData;\r
33EFI_HII_HANDLE gFrontPageHandle;\r
7936fb6a 34UINTN gClassOfVfr;\r
35UINTN gFunctionKeySetting;\r
36BOOLEAN gResetRequired;\r
37BOOLEAN gNvUpdateRequired;\r
38EFI_HII_HANDLE gHiiHandle;\r
7936fb6a 39UINT16 gDirection;\r
40EFI_SCREEN_DESCRIPTOR gScreenDimensions;\r
41BOOLEAN gUpArrow;\r
42BOOLEAN gDownArrow;\r
43\r
44//\r
45// Browser Global Strings\r
46//\r
47CHAR16 *gFunctionOneString;\r
7936fb6a 48CHAR16 *gFunctionNineString;\r
49CHAR16 *gFunctionTenString;\r
50CHAR16 *gEnterString;\r
51CHAR16 *gEnterCommitString;\r
8d00a0f1 52CHAR16 *gEnterEscapeString;\r
7936fb6a 53CHAR16 *gEscapeString;\r
54CHAR16 *gSaveFailed;\r
55CHAR16 *gMoveHighlight;\r
56CHAR16 *gMakeSelection;\r
57CHAR16 *gDecNumericInput;\r
58CHAR16 *gHexNumericInput;\r
59CHAR16 *gToggleCheckBox;\r
60CHAR16 *gPromptForData;\r
61CHAR16 *gPromptForPassword;\r
62CHAR16 *gPromptForNewPassword;\r
63CHAR16 *gConfirmPassword;\r
64CHAR16 *gConfirmError;\r
65CHAR16 *gPassowordInvalid;\r
66CHAR16 *gPressEnter;\r
67CHAR16 *gEmptyString;\r
68CHAR16 *gAreYouSure;\r
69CHAR16 *gYesResponse;\r
70CHAR16 *gNoResponse;\r
71CHAR16 *gMiniString;\r
72CHAR16 *gPlusString;\r
73CHAR16 *gMinusString;\r
74CHAR16 *gAdjustNumber;\r
ebe43565 75CHAR16 *gSaveChanges;\r
8d00a0f1 76CHAR16 *gOptionMismatch;\r
7936fb6a 77\r
0e8e994d 78CHAR16 *mUnknownString = L"!";\r
79\r
7936fb6a 80CHAR16 gPromptBlockWidth;\r
81CHAR16 gOptionBlockWidth;\r
82CHAR16 gHelpBlockWidth;\r
83\r
84EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
85EFI_GUID gSetupBrowserGuid = {\r
86 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}\r
87};\r
88\r
d66e6c16 89FORM_BROWSER_FORMSET *gOldFormSet = NULL;\r
90\r
7936fb6a 91FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {\r
92 //\r
93 // Boot Manager\r
94 //\r
95 {\r
96 {\r
97 0x847bc3fe,\r
98 0xb974,\r
99 0x446d,\r
100 {\r
101 0x94,\r
102 0x49,\r
103 0x5a,\r
104 0xd5,\r
105 0x41,\r
106 0x2e,\r
107 0x99,\r
108 0x3b\r
109 }\r
110 },\r
111 NONE_FUNCTION_KEY_SETTING\r
112 },\r
113 //\r
114 // Device Manager\r
115 //\r
116 {\r
117 {\r
118 0x3ebfa8e6,\r
119 0x511d,\r
120 0x4b5b,\r
121 {\r
122 0xa9,\r
123 0x5f,\r
124 0xfb,\r
125 0x38,\r
126 0x26,\r
127 0xf,\r
128 0x1c,\r
129 0x27\r
130 }\r
131 },\r
132 NONE_FUNCTION_KEY_SETTING\r
133 },\r
134 //\r
135 // BMM FormSet.\r
136 //\r
137 {\r
138 {\r
139 0x642237c7,\r
140 0x35d4,\r
141 0x472d,\r
142 {\r
143 0x83,\r
144 0x65,\r
145 0x12,\r
146 0xe0,\r
147 0xcc,\r
148 0xf2,\r
149 0x7a,\r
150 0x22\r
151 }\r
152 },\r
153 NONE_FUNCTION_KEY_SETTING\r
154 },\r
155 //\r
156 // BMM File Explorer FormSet.\r
157 //\r
158 {\r
159 {\r
160 0x1f2d63e1,\r
161 0xfebd,\r
162 0x4dc7,\r
163 {\r
164 0x9c,\r
165 0xc5,\r
166 0xba,\r
167 0x2b,\r
168 0x1c,\r
169 0xef,\r
170 0x9c,\r
171 0x5b\r
172 }\r
173 },\r
174 NONE_FUNCTION_KEY_SETTING\r
175 },\r
176};\r
177\r
178/**\r
179 This is the routine which an external caller uses to direct the browser\r
180 where to obtain it's information.\r
181\r
182\r
183 @param This The Form Browser protocol instanse.\r
184 @param Handles A pointer to an array of Handles. If HandleCount > 1 we\r
185 display a list of the formsets for the handles specified.\r
186 @param HandleCount The number of Handles specified in Handle.\r
187 @param FormSetGuid This field points to the EFI_GUID which must match the Guid\r
188 field in the EFI_IFR_FORM_SET op-code for the specified\r
189 forms-based package. If FormSetGuid is NULL, then this\r
190 function will display the first found forms package.\r
191 @param FormId This field specifies which EFI_IFR_FORM to render as the first\r
192 displayable page. If this field has a value of 0x0000, then\r
193 the forms browser will render the specified forms in their encoded order.\r
d66e6c16 194 @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in\r
7936fb6a 195 characters.\r
f02d0c0f 196 @param ActionRequest Points to the action recommended by the form.\r
7936fb6a 197\r
198 @retval EFI_SUCCESS The function completed successfully.\r
199 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
200 @retval EFI_NOT_FOUND No valid forms could be found to display.\r
201\r
202**/\r
203EFI_STATUS\r
204EFIAPI\r
205SendForm (\r
206 IN CONST EFI_FORM_BROWSER2_PROTOCOL *This,\r
207 IN EFI_HII_HANDLE *Handles,\r
208 IN UINTN HandleCount,\r
209 IN EFI_GUID *FormSetGuid, OPTIONAL\r
210 IN UINT16 FormId, OPTIONAL\r
211 IN CONST EFI_SCREEN_DESCRIPTOR *ScreenDimensions, OPTIONAL\r
212 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest OPTIONAL\r
213 )\r
214{\r
519f076a 215 EFI_STATUS Status;\r
216 UI_MENU_SELECTION *Selection;\r
217 UINTN Index;\r
218 FORM_BROWSER_FORMSET *FormSet;\r
7936fb6a 219\r
220 Status = EFI_SUCCESS;\r
221 ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
222\r
223 //\r
224 // Seed the dimensions in the global\r
225 //\r
226 gST->ConOut->QueryMode (\r
227 gST->ConOut,\r
228 gST->ConOut->Mode->Mode,\r
229 &gScreenDimensions.RightColumn,\r
230 &gScreenDimensions.BottomRow\r
231 );\r
232\r
233 if (ScreenDimensions != NULL) {\r
234 //\r
235 // Check local dimension vs. global dimension.\r
236 //\r
237 if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||\r
238 (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)\r
239 ) {\r
240 return EFI_INVALID_PARAMETER;\r
241 } else {\r
242 //\r
243 // Local dimension validation.\r
244 //\r
245 if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&\r
246 (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&\r
247 ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&\r
248 (\r
249 (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +\r
250 SCROLL_ARROW_HEIGHT *\r
251 2 +\r
252 FRONT_PAGE_HEADER_HEIGHT +\r
253 FOOTER_HEIGHT +\r
254 1\r
255 )\r
256 ) {\r
257 CopyMem (&gScreenDimensions, (VOID *) ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
258 } else {\r
259 return EFI_INVALID_PARAMETER;\r
260 }\r
261 }\r
262 }\r
263\r
264 gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);\r
265 gHelpBlockWidth = gOptionBlockWidth;\r
266 gPromptBlockWidth = gOptionBlockWidth;\r
267\r
268 //\r
269 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed\r
270 //\r
271 InitializeBrowserStrings ();\r
272\r
273 gFunctionKeySetting = DEFAULT_FUNCTION_KEY_SETTING;\r
0a1147ed 274 gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;\r
7936fb6a 275\r
276 //\r
277 // Ensure we are in Text mode\r
278 //\r
ebe43565 279 gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
519f076a 280\r
7936fb6a 281 for (Index = 0; Index < HandleCount; Index++) {\r
282 Selection = AllocateZeroPool (sizeof (UI_MENU_SELECTION));\r
283 ASSERT (Selection != NULL);\r
284\r
285 Selection->Handle = Handles[Index];\r
286 if (FormSetGuid != NULL) {\r
287 CopyMem (&Selection->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));\r
288 Selection->FormId = FormId;\r
289 }\r
290\r
d66e6c16 291 gNvUpdateRequired = FALSE;\r
292\r
7936fb6a 293 do {\r
294 FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
295 ASSERT (FormSet != NULL);\r
296\r
297 //\r
298 // Initialize internal data structures of FormSet\r
299 //\r
300 Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet);\r
e8e36190 301 if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) {\r
7936fb6a 302 DestroyFormSet (FormSet);\r
303 break;\r
304 }\r
305 Selection->FormSet = FormSet;\r
306\r
7936fb6a 307 //\r
308 // Display this formset\r
309 //\r
310 gCurrentSelection = Selection;\r
311\r
312 Status = SetupBrowser (Selection);\r
313\r
314 gCurrentSelection = NULL;\r
7936fb6a 315\r
316 if (EFI_ERROR (Status)) {\r
317 break;\r
318 }\r
319\r
320 } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);\r
321\r
d66e6c16 322 if (gOldFormSet != NULL) {\r
323 DestroyFormSet (gOldFormSet);\r
324 gOldFormSet = NULL;\r
325 }\r
326\r
f4113e1f 327 FreePool (Selection);\r
7936fb6a 328 }\r
329\r
330 if (ActionRequest != NULL) {\r
331 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
332 if (gResetRequired) {\r
333 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
334 }\r
335 }\r
336\r
337 FreeBrowserStrings ();\r
338\r
339 gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
340 gST->ConOut->ClearScreen (gST->ConOut);\r
341\r
342 return Status;\r
343}\r
344\r
345\r
346/**\r
347 This function is called by a callback handler to retrieve uncommitted state\r
348 data from the browser.\r
349\r
350 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL\r
351 instance.\r
352 @param ResultsDataSize A pointer to the size of the buffer associated\r
353 with ResultsData.\r
354 @param ResultsData A string returned from an IFR browser or\r
355 equivalent. The results string will have no\r
356 routing information in them.\r
357 @param RetrieveData A BOOLEAN field which allows an agent to retrieve\r
358 (if RetrieveData = TRUE) data from the uncommitted\r
359 browser state information or set (if RetrieveData\r
360 = FALSE) data in the uncommitted browser state\r
361 information.\r
362 @param VariableGuid An optional field to indicate the target variable\r
363 GUID name to use.\r
364 @param VariableName An optional field to indicate the target\r
365 human-readable variable name.\r
366\r
367 @retval EFI_SUCCESS The results have been distributed or are awaiting\r
368 distribution.\r
369 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to\r
370 contain the results data.\r
371\r
372**/\r
373EFI_STATUS\r
374EFIAPI\r
375BrowserCallback (\r
376 IN CONST EFI_FORM_BROWSER2_PROTOCOL *This,\r
377 IN OUT UINTN *ResultsDataSize,\r
378 IN OUT EFI_STRING ResultsData,\r
379 IN BOOLEAN RetrieveData,\r
380 IN CONST EFI_GUID *VariableGuid, OPTIONAL\r
381 IN CONST CHAR16 *VariableName OPTIONAL\r
382 )\r
383{\r
384 EFI_STATUS Status;\r
385 LIST_ENTRY *Link;\r
386 FORMSET_STORAGE *Storage;\r
387 FORM_BROWSER_FORMSET *FormSet;\r
388 BOOLEAN Found;\r
389 CHAR16 *ConfigResp;\r
390 CHAR16 *StrPtr;\r
391 UINTN BufferSize;\r
392 UINTN TmpSize;\r
393\r
394 if (ResultsDataSize == NULL || ResultsData == NULL) {\r
395 return EFI_INVALID_PARAMETER;\r
396 }\r
397\r
398 if (gCurrentSelection == NULL) {\r
399 return EFI_NOT_READY;\r
400 }\r
401\r
402 Storage = NULL;\r
403 ConfigResp = NULL;\r
404 FormSet = gCurrentSelection->FormSet;\r
405\r
406 //\r
407 // Find target storage\r
408 //\r
409 Link = GetFirstNode (&FormSet->StorageListHead);\r
410 if (IsNull (&FormSet->StorageListHead, Link)) {\r
411 return EFI_UNSUPPORTED;\r
412 }\r
413\r
414 if (VariableGuid != NULL) {\r
415 //\r
416 // Try to find target storage\r
417 //\r
418 Found = FALSE;\r
419 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
420 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
421 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
422\r
423 if (CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) {\r
424 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
425 //\r
426 // Buffer storage require both GUID and Name\r
427 //\r
428 if (VariableName == NULL) {\r
429 return EFI_NOT_FOUND;\r
430 }\r
431\r
432 if (StrCmp (Storage->Name, (CHAR16 *) VariableName) != 0) {\r
433 continue;\r
434 }\r
435 }\r
436 Found = TRUE;\r
437 break;\r
438 }\r
439 }\r
440\r
441 if (!Found) {\r
442 return EFI_NOT_FOUND;\r
443 }\r
444 } else {\r
445 //\r
446 // GUID/Name is not specified, take the first storage in FormSet\r
447 //\r
448 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
449 }\r
450\r
451 if (RetrieveData) {\r
452 //\r
453 // Skip if there is no RequestElement\r
454 //\r
455 if (Storage->ElementCount == 0) {\r
456 return EFI_SUCCESS;\r
457 }\r
458\r
459 //\r
460 // Generate <ConfigResp>\r
461 //\r
462 Status = StorageToConfigResp (Storage, &ConfigResp);\r
463 if (EFI_ERROR (Status)) {\r
464 return Status;\r
465 }\r
466\r
467 //\r
468 // Skip <ConfigHdr> and '&' to point to <ConfigBody>\r
469 //\r
470 StrPtr = ConfigResp + StrLen (Storage->ConfigHdr) + 1;\r
471\r
472 BufferSize = StrSize (StrPtr);\r
473 if (*ResultsDataSize < BufferSize) {\r
474 *ResultsDataSize = BufferSize;\r
475\r
f4113e1f 476 FreePool (ConfigResp);\r
7936fb6a 477 return EFI_BUFFER_TOO_SMALL;\r
478 }\r
479\r
480 *ResultsDataSize = BufferSize;\r
481 CopyMem (ResultsData, StrPtr, BufferSize);\r
482\r
f4113e1f 483 FreePool (ConfigResp);\r
7936fb6a 484 } else {\r
485 //\r
486 // Prepare <ConfigResp>\r
487 //\r
488 TmpSize = StrLen (ResultsData);\r
489 BufferSize = (TmpSize + StrLen (Storage->ConfigHdr) + 2) * sizeof (CHAR16);\r
490 ConfigResp = AllocateZeroPool (BufferSize);\r
491 ASSERT (ConfigResp != NULL);\r
492\r
493 StrCpy (ConfigResp, Storage->ConfigHdr);\r
494 StrCat (ConfigResp, L"&");\r
495 StrCat (ConfigResp, ResultsData);\r
496\r
497 //\r
498 // Update Browser uncommited data\r
499 //\r
500 Status = ConfigRespToStorage (Storage, ConfigResp);\r
501 if (EFI_ERROR (Status)) {\r
502 return Status;\r
503 }\r
504 }\r
505\r
506 return EFI_SUCCESS;\r
507}\r
508\r
509\r
510/**\r
511 Initialize Setup Browser driver.\r
512\r
513 @param ImageHandle The image handle.\r
514 @param SystemTable The system table.\r
515\r
516 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..\r
517 @return Other value if failed to initialize the Setup Browser module.\r
518\r
519**/\r
520EFI_STATUS\r
521EFIAPI\r
522InitializeSetup (\r
523 IN EFI_HANDLE ImageHandle,\r
524 IN EFI_SYSTEM_TABLE *SystemTable\r
525 )\r
526{\r
527 EFI_STATUS Status;\r
7936fb6a 528\r
529 //\r
530 // Locate required Hii relative protocols\r
531 //\r
532 Status = gBS->LocateProtocol (\r
533 &gEfiHiiDatabaseProtocolGuid,\r
534 NULL,\r
535 (VOID **) &mHiiDatabase\r
536 );\r
537 ASSERT_EFI_ERROR (Status);\r
538\r
539 Status = gBS->LocateProtocol (\r
540 &gEfiHiiStringProtocolGuid,\r
541 NULL,\r
542 (VOID **) &mHiiString\r
543 );\r
544 ASSERT_EFI_ERROR (Status);\r
545\r
546 Status = gBS->LocateProtocol (\r
547 &gEfiHiiConfigRoutingProtocolGuid,\r
548 NULL,\r
549 (VOID **) &mHiiConfigRouting\r
550 );\r
551 ASSERT_EFI_ERROR (Status);\r
552\r
553 //\r
554 // Publish our HII data\r
555 //\r
cb7d01c0 556 gHiiHandle = HiiAddPackages (\r
557 &gSetupBrowserGuid,\r
558 ImageHandle,\r
559 SetupBrowserStrings,\r
560 NULL\r
561 );\r
562 ASSERT (gHiiHandle != NULL);\r
7936fb6a 563\r
564 //\r
565 // Initialize Driver private data\r
566 //\r
0a1147ed
LG
567 gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));\r
568 ASSERT (gBannerData != NULL);\r
7936fb6a 569\r
570 //\r
571 // Install FormBrowser2 protocol\r
572 //\r
573 mPrivateData.Handle = NULL;\r
574 Status = gBS->InstallProtocolInterface (\r
575 &mPrivateData.Handle,\r
576 &gEfiFormBrowser2ProtocolGuid,\r
577 EFI_NATIVE_INTERFACE,\r
578 &mPrivateData.FormBrowser2\r
579 );\r
580 ASSERT_EFI_ERROR (Status);\r
581\r
7936fb6a 582 return Status;\r
583}\r
584\r
585\r
586/**\r
587 Create a new string in HII Package List.\r
588\r
589 @param String The String to be added\r
590 @param HiiHandle The package list in the HII database to insert the\r
591 specified string.\r
592\r
593 @return The output string.\r
594\r
595**/\r
596EFI_STRING_ID\r
597NewString (\r
598 IN CHAR16 *String,\r
599 IN EFI_HII_HANDLE HiiHandle\r
600 )\r
601{\r
602 EFI_STRING_ID StringId;\r
7936fb6a 603\r
cb7d01c0 604 StringId = HiiSetString (HiiHandle, 0, String, NULL);\r
605 ASSERT (StringId != 0);\r
7936fb6a 606\r
607 return StringId;\r
608}\r
609\r
610\r
611/**\r
612 Delete a string from HII Package List.\r
613\r
614 @param StringId Id of the string in HII database.\r
615 @param HiiHandle The HII package list handle.\r
616\r
617 @retval EFI_SUCCESS The string was deleted successfully.\r
618\r
619**/\r
620EFI_STATUS\r
621DeleteString (\r
622 IN EFI_STRING_ID StringId,\r
623 IN EFI_HII_HANDLE HiiHandle\r
624 )\r
625{\r
626 CHAR16 NullChar;\r
627\r
628 NullChar = CHAR_NULL;\r
cb7d01c0 629 HiiSetString (HiiHandle, StringId, &NullChar, NULL);\r
630 return EFI_SUCCESS;\r
7936fb6a 631}\r
632\r
633\r
634/**\r
635 Get the string based on the StringId and HII Package List Handle.\r
636\r
637 @param Token The String's ID.\r
638 @param HiiHandle The package list in the HII database to search for\r
639 the specified string.\r
640\r
641 @return The output string.\r
642\r
643**/\r
644CHAR16 *\r
645GetToken (\r
646 IN EFI_STRING_ID Token,\r
647 IN EFI_HII_HANDLE HiiHandle\r
648 )\r
649{\r
cb7d01c0 650 EFI_STRING String;\r
7936fb6a 651\r
cb7d01c0 652 String = HiiGetString (HiiHandle, Token, NULL);\r
0e8e994d 653 if (String == NULL) {\r
654 String = AllocateCopyPool (sizeof (mUnknownString), mUnknownString);\r
655 ASSERT (String != NULL);\r
656 }\r
cb7d01c0 657 return (CHAR16 *) String;\r
7936fb6a 658}\r
659\r
660\r
661/**\r
662 Allocate new memory and then copy the Unicode string Source to Destination.\r
663\r
664 @param Dest Location to copy string\r
665 @param Src String to copy\r
666\r
667**/\r
668VOID\r
669NewStringCpy (\r
670 IN OUT CHAR16 **Dest,\r
671 IN CHAR16 *Src\r
672 )\r
673{\r
676df92c 674 if (*Dest != NULL) {\r
675 FreePool (*Dest);\r
676 }\r
7936fb6a 677 *Dest = AllocateCopyPool (StrSize (Src), Src);\r
678 ASSERT (*Dest != NULL);\r
679}\r
680\r
681\r
682/**\r
683 Allocate new memory and concatinate Source on the end of Destination.\r
684\r
685 @param Dest String to added to the end of.\r
686 @param Src String to concatinate.\r
687\r
688**/\r
689VOID\r
690NewStringCat (\r
691 IN OUT CHAR16 **Dest,\r
692 IN CHAR16 *Src\r
693 )\r
694{\r
695 CHAR16 *NewString;\r
696 UINTN TmpSize;\r
697\r
698 if (*Dest == NULL) {\r
699 NewStringCpy (Dest, Src);\r
700 return;\r
701 }\r
702\r
703 TmpSize = StrSize (*Dest);\r
704 NewString = AllocateZeroPool (TmpSize + StrSize (Src) - 1);\r
705 ASSERT (NewString != NULL);\r
706\r
707 StrCpy (NewString, *Dest);\r
708 StrCat (NewString, Src);\r
709\r
f4113e1f 710 FreePool (*Dest);\r
7936fb6a 711 *Dest = NewString;\r
712}\r
713\r
714\r
715/**\r
716 Synchronize Storage's Edit copy to Shadow copy.\r
717\r
718 @param Storage The Storage to be synchronized.\r
719\r
720**/\r
721VOID\r
722SynchronizeStorage (\r
723 IN FORMSET_STORAGE *Storage\r
724 )\r
725{\r
726 LIST_ENTRY *Link;\r
727 NAME_VALUE_NODE *Node;\r
728\r
729 switch (Storage->Type) {\r
730 case EFI_HII_VARSTORE_BUFFER:\r
731 CopyMem (Storage->Buffer, Storage->EditBuffer, Storage->Size);\r
732 break;\r
733\r
734 case EFI_HII_VARSTORE_NAME_VALUE:\r
735 Link = GetFirstNode (&Storage->NameValueListHead);\r
736 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
737 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
738\r
739 NewStringCpy (&Node->Value, Node->EditValue);\r
740\r
741 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
742 }\r
743 break;\r
744\r
745 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
746 default:\r
747 break;\r
748 }\r
749}\r
750\r
751\r
752/**\r
753 Get Value for given Name from a NameValue Storage.\r
754\r
755 @param Storage The NameValue Storage.\r
756 @param Name The Name.\r
757 @param Value The retured Value.\r
758\r
759 @retval EFI_SUCCESS Value found for given Name.\r
760 @retval EFI_NOT_FOUND No such Name found in NameValue storage.\r
761\r
762**/\r
763EFI_STATUS\r
764GetValueByName (\r
765 IN FORMSET_STORAGE *Storage,\r
766 IN CHAR16 *Name,\r
767 IN OUT CHAR16 **Value\r
768 )\r
769{\r
770 LIST_ENTRY *Link;\r
771 NAME_VALUE_NODE *Node;\r
772\r
773 *Value = NULL;\r
774\r
775 Link = GetFirstNode (&Storage->NameValueListHead);\r
776 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
777 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
778\r
779 if (StrCmp (Name, Node->Name) == 0) {\r
780 NewStringCpy (Value, Node->EditValue);\r
781 return EFI_SUCCESS;\r
782 }\r
783\r
784 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
785 }\r
786\r
787 return EFI_NOT_FOUND;\r
788}\r
789\r
790\r
791/**\r
792 Set Value of given Name in a NameValue Storage.\r
793\r
794 @param Storage The NameValue Storage.\r
795 @param Name The Name.\r
796 @param Value The Value to set.\r
797\r
798 @retval EFI_SUCCESS Value found for given Name.\r
799 @retval EFI_NOT_FOUND No such Name found in NameValue storage.\r
800\r
801**/\r
802EFI_STATUS\r
803SetValueByName (\r
804 IN FORMSET_STORAGE *Storage,\r
805 IN CHAR16 *Name,\r
806 IN CHAR16 *Value\r
807 )\r
808{\r
809 LIST_ENTRY *Link;\r
810 NAME_VALUE_NODE *Node;\r
811\r
812 Link = GetFirstNode (&Storage->NameValueListHead);\r
813 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
814 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
815\r
816 if (StrCmp (Name, Node->Name) == 0) {\r
676df92c 817 if (Node->EditValue != NULL) {\r
818 FreePool (Node->EditValue);\r
819 }\r
7936fb6a 820 Node->EditValue = AllocateCopyPool (StrSize (Value), Value);\r
821 ASSERT (Node->EditValue != NULL);\r
822 return EFI_SUCCESS;\r
823 }\r
824\r
825 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
826 }\r
827\r
828 return EFI_NOT_FOUND;\r
829}\r
830\r
831\r
832/**\r
833 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.\r
834\r
835 @param Storage The Storage to be conveted.\r
836 @param ConfigResp The returned <ConfigResp>.\r
837\r
838 @retval EFI_SUCCESS Convert success.\r
839 @retval EFI_INVALID_PARAMETER Incorrect storage type.\r
840\r
841**/\r
842EFI_STATUS\r
843StorageToConfigResp (\r
844 IN FORMSET_STORAGE *Storage,\r
845 IN CHAR16 **ConfigResp\r
846 )\r
847{\r
848 EFI_STATUS Status;\r
849 EFI_STRING Progress;\r
850 LIST_ENTRY *Link;\r
851 NAME_VALUE_NODE *Node;\r
852\r
853 Status = EFI_SUCCESS;\r
854\r
855 switch (Storage->Type) {\r
856 case EFI_HII_VARSTORE_BUFFER:\r
857 Status = mHiiConfigRouting->BlockToConfig (\r
858 mHiiConfigRouting,\r
859 Storage->ConfigRequest,\r
860 Storage->EditBuffer,\r
861 Storage->Size,\r
862 ConfigResp,\r
863 &Progress\r
864 );\r
865 break;\r
866\r
867 case EFI_HII_VARSTORE_NAME_VALUE:\r
868 *ConfigResp = NULL;\r
869 NewStringCat (ConfigResp, Storage->ConfigHdr);\r
870\r
871 Link = GetFirstNode (&Storage->NameValueListHead);\r
872 while (!IsNull (&Storage->NameValueListHead, Link)) {\r
873 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
874\r
875 NewStringCat (ConfigResp, L"&");\r
876 NewStringCat (ConfigResp, Node->Name);\r
877 NewStringCat (ConfigResp, L"=");\r
878 NewStringCat (ConfigResp, Node->EditValue);\r
879\r
880 Link = GetNextNode (&Storage->NameValueListHead, Link);\r
881 }\r
882 break;\r
883\r
884 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
885 default:\r
886 Status = EFI_INVALID_PARAMETER;\r
887 break;\r
888 }\r
889\r
890 return Status;\r
891}\r
892\r
893\r
894/**\r
895 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.\r
896\r
897 @param Storage The Storage to receive the settings.\r
898 @param ConfigResp The <ConfigResp> to be converted.\r
899\r
900 @retval EFI_SUCCESS Convert success.\r
901 @retval EFI_INVALID_PARAMETER Incorrect storage type.\r
902\r
903**/\r
904EFI_STATUS\r
905ConfigRespToStorage (\r
906 IN FORMSET_STORAGE *Storage,\r
907 IN CHAR16 *ConfigResp\r
908 )\r
909{\r
910 EFI_STATUS Status;\r
911 EFI_STRING Progress;\r
912 UINTN BufferSize;\r
913 CHAR16 *StrPtr;\r
914 CHAR16 *Name;\r
915 CHAR16 *Value;\r
916\r
917 Status = EFI_SUCCESS;\r
918\r
919 switch (Storage->Type) {\r
920 case EFI_HII_VARSTORE_BUFFER:\r
921 BufferSize = Storage->Size;\r
922 Status = mHiiConfigRouting->ConfigToBlock (\r
923 mHiiConfigRouting,\r
924 ConfigResp,\r
925 Storage->EditBuffer,\r
926 &BufferSize,\r
927 &Progress\r
928 );\r
929 break;\r
930\r
931 case EFI_HII_VARSTORE_NAME_VALUE:\r
932 StrPtr = StrStr (ConfigResp, L"&");\r
933 while (StrPtr != NULL) {\r
934 //\r
935 // Skip '&'\r
936 //\r
937 StrPtr = StrPtr + 1;\r
938 Name = StrPtr;\r
939 StrPtr = StrStr (StrPtr, L"=");\r
940 if (StrPtr == NULL) {\r
941 break;\r
942 }\r
943 *StrPtr = 0;\r
944\r
945 //\r
946 // Skip '='\r
947 //\r
948 StrPtr = StrPtr + 1;\r
949 Value = StrPtr;\r
950 StrPtr = StrStr (StrPtr, L"&");\r
951 if (StrPtr != NULL) {\r
952 *StrPtr = 0;\r
953 }\r
954 SetValueByName (Storage, Name, Value);\r
955 }\r
956 break;\r
957\r
958 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
959 default:\r
960 Status = EFI_INVALID_PARAMETER;\r
961 break;\r
962 }\r
963\r
964 return Status;\r
965}\r
966\r
967\r
968/**\r
969 Get Question's current Value.\r
970\r
971 @param FormSet FormSet data structure.\r
972 @param Form Form data structure.\r
973 @param Question Question to be initialized.\r
974 @param Cached TRUE: get from Edit copy FALSE: get from original\r
975 Storage\r
976\r
977 @retval EFI_SUCCESS The function completed successfully.\r
978\r
979**/\r
980EFI_STATUS\r
981GetQuestionValue (\r
982 IN FORM_BROWSER_FORMSET *FormSet,\r
983 IN FORM_BROWSER_FORM *Form,\r
984 IN OUT FORM_BROWSER_STATEMENT *Question,\r
985 IN BOOLEAN Cached\r
986 )\r
987{\r
988 EFI_STATUS Status;\r
989 BOOLEAN Enabled;\r
990 BOOLEAN Pending;\r
991 UINT8 *Dst;\r
992 UINTN StorageWidth;\r
993 EFI_TIME EfiTime;\r
994 FORMSET_STORAGE *Storage;\r
995 EFI_IFR_TYPE_VALUE *QuestionValue;\r
996 CHAR16 *ConfigRequest;\r
997 CHAR16 *Progress;\r
998 CHAR16 *Result;\r
999 CHAR16 *Value;\r
8d00a0f1 1000 CHAR16 *StringPtr;\r
7936fb6a 1001 UINTN Length;\r
63d55bb9
LG
1002 UINTN Index;\r
1003 UINTN LengthStr;\r
7936fb6a 1004 BOOLEAN IsBufferStorage;\r
1005 BOOLEAN IsString;\r
63d55bb9
LG
1006 CHAR16 TemStr[5];\r
1007 UINT8 DigitUint8;\r
7936fb6a 1008\r
1009 Status = EFI_SUCCESS;\r
1010\r
1011 //\r
1012 // Statement don't have storage, skip them\r
1013 //\r
1014 if (Question->QuestionId == 0) {\r
1015 return Status;\r
1016 }\r
1017\r
1018 //\r
1019 // Question value is provided by an Expression, evaluate it\r
1020 //\r
1021 if (Question->ValueExpression != NULL) {\r
1022 Status = EvaluateExpression (FormSet, Form, Question->ValueExpression);\r
1023 if (!EFI_ERROR (Status)) {\r
1024 CopyMem (&Question->HiiValue, &Question->ValueExpression->Result, sizeof (EFI_HII_VALUE));\r
1025 }\r
1026 return Status;\r
1027 }\r
1028\r
1029 //\r
1030 // Question value is provided by RTC\r
1031 //\r
1032 Storage = Question->Storage;\r
1033 QuestionValue = &Question->HiiValue.Value;\r
1034 if (Storage == NULL) {\r
1035 //\r
1036 // It's a Question without storage, or RTC date/time\r
1037 //\r
1038 if (Question->Operand == EFI_IFR_DATE_OP || Question->Operand == EFI_IFR_TIME_OP) {\r
1039 //\r
1040 // Date and time define the same Flags bit\r
1041 //\r
1042 switch (Question->Flags & EFI_QF_DATE_STORAGE) {\r
1043 case QF_DATE_STORAGE_TIME:\r
1044 Status = gRT->GetTime (&EfiTime, NULL);\r
1045 break;\r
1046\r
1047 case QF_DATE_STORAGE_WAKEUP:\r
1048 Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);\r
1049 break;\r
1050\r
1051 case QF_DATE_STORAGE_NORMAL:\r
1052 default:\r
1053 //\r
1054 // For date/time without storage\r
1055 //\r
1056 return EFI_SUCCESS;\r
1057 }\r
1058\r
1059 if (EFI_ERROR (Status)) {\r
1060 return Status;\r
1061 }\r
1062\r
1063 if (Question->Operand == EFI_IFR_DATE_OP) {\r
1064 QuestionValue->date.Year = EfiTime.Year;\r
1065 QuestionValue->date.Month = EfiTime.Month;\r
1066 QuestionValue->date.Day = EfiTime.Day;\r
1067 } else {\r
1068 QuestionValue->time.Hour = EfiTime.Hour;\r
1069 QuestionValue->time.Minute = EfiTime.Minute;\r
1070 QuestionValue->time.Second = EfiTime.Second;\r
1071 }\r
1072 }\r
1073\r
1074 return EFI_SUCCESS;\r
1075 }\r
1076\r
1077 //\r
1078 // Question value is provided by EFI variable\r
1079 //\r
1080 StorageWidth = Question->StorageWidth;\r
1081 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
1082 if (Question->BufferValue != NULL) {\r
1083 Dst = Question->BufferValue;\r
1084 } else {\r
1085 Dst = (UINT8 *) QuestionValue;\r
1086 }\r
1087\r
1088 Status = gRT->GetVariable (\r
1089 Question->VariableName,\r
1090 &Storage->Guid,\r
1091 NULL,\r
1092 &StorageWidth,\r
1093 Dst\r
1094 );\r
1095 //\r
1096 // Always return success, even this EFI variable doesn't exist\r
1097 //\r
1098 return EFI_SUCCESS;\r
1099 }\r
1100\r
1101 //\r
1102 // Question Value is provided by Buffer Storage or NameValue Storage\r
1103 //\r
1104 if (Question->BufferValue != NULL) {\r
1105 //\r
1106 // This Question is password or orderedlist\r
1107 //\r
1108 Dst = Question->BufferValue;\r
1109 } else {\r
1110 //\r
1111 // Other type of Questions\r
1112 //\r
1113 Dst = (UINT8 *) &Question->HiiValue.Value;\r
1114 }\r
1115\r
1116 IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);\r
1117 IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
1118 if (Cached) {\r
1119 if (IsBufferStorage) {\r
1120 //\r
1121 // Copy from storage Edit buffer\r
1122 //\r
1123 CopyMem (Dst, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
1124 } else {\r
1125 Status = GetValueByName (Storage, Question->VariableName, &Value);\r
1126 if (EFI_ERROR (Status)) {\r
1127 return Status;\r
1128 }\r
d66e6c16 1129\r
63d55bb9
LG
1130 LengthStr = StrLen (Value);\r
1131 Status = EFI_SUCCESS;\r
7936fb6a 1132 if (IsString) {\r
1133 //\r
1134 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
63d55bb9 1135 // Add string tail char L'\0' into Length\r
7936fb6a 1136 //\r
63d55bb9
LG
1137 Length = StorageWidth + sizeof (CHAR16);\r
1138 if (Length < ((LengthStr / 4 + 1) * 2)) {\r
1139 Status = EFI_BUFFER_TOO_SMALL;\r
1140 } else {\r
1141 StringPtr = (CHAR16 *) Dst;\r
1142 ZeroMem (TemStr, sizeof (TemStr));\r
1143 for (Index = 0; Index < LengthStr; Index += 4) {\r
1144 StrnCpy (TemStr, Value + Index, 4);\r
1145 StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
1146 }\r
1147 //\r
1148 // Add tailing L'\0' character\r
1149 //\r
1150 StringPtr[Index/4] = L'\0';\r
1151 }\r
7936fb6a 1152 } else {\r
63d55bb9
LG
1153 if (StorageWidth < ((LengthStr + 1) / 2)) {\r
1154 Status = EFI_BUFFER_TOO_SMALL;\r
1155 } else {\r
1156 ZeroMem (TemStr, sizeof (TemStr));\r
1157 for (Index = 0; Index < LengthStr; Index ++) {\r
1158 TemStr[0] = Value[LengthStr - Index - 1];\r
1159 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
1160 if ((Index & 1) == 0) {\r
1161 Dst [Index/2] = DigitUint8;\r
1162 } else {\r
634303c9 1163 Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
63d55bb9
LG
1164 }\r
1165 }\r
1166 }\r
7936fb6a 1167 }\r
1168\r
f4113e1f 1169 FreePool (Value);\r
7936fb6a 1170 }\r
1171 } else {\r
1172 //\r
1173 // Request current settings from Configuration Driver\r
1174 //\r
1175 if (FormSet->ConfigAccess == NULL) {\r
1176 return EFI_NOT_FOUND;\r
1177 }\r
1178\r
1179 //\r
1180 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||\r
1181 // <ConfigHdr> + "&" + <VariableName>\r
1182 //\r
1183 if (IsBufferStorage) {\r
1184 Length = StrLen (Storage->ConfigHdr);\r
1185 Length += StrLen (Question->BlockName);\r
1186 } else {\r
1187 Length = StrLen (Storage->ConfigHdr);\r
1188 Length += StrLen (Question->VariableName) + 1;\r
1189 }\r
1190 ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));\r
1191 ASSERT (ConfigRequest != NULL);\r
1192\r
1193 StrCpy (ConfigRequest, Storage->ConfigHdr);\r
1194 if (IsBufferStorage) {\r
1195 StrCat (ConfigRequest, Question->BlockName);\r
1196 } else {\r
1197 StrCat (ConfigRequest, L"&");\r
1198 StrCat (ConfigRequest, Question->VariableName);\r
1199 }\r
1200\r
1201 Status = FormSet->ConfigAccess->ExtractConfig (\r
1202 FormSet->ConfigAccess,\r
1203 ConfigRequest,\r
1204 &Progress,\r
1205 &Result\r
1206 );\r
1207 if (EFI_ERROR (Status)) {\r
1208 return Status;\r
1209 }\r
1210\r
1211 //\r
1212 // Skip <ConfigRequest>\r
1213 //\r
1214 Value = Result + Length;\r
1215 if (IsBufferStorage) {\r
1216 //\r
1217 // Skip "&VALUE"\r
1218 //\r
1219 Value = Value + 6;\r
1220 }\r
1221 if (*Value != '=') {\r
f4113e1f 1222 FreePool (Result);\r
7936fb6a 1223 return EFI_NOT_FOUND;\r
1224 }\r
1225 //\r
1226 // Skip '=', point to value\r
1227 //\r
1228 Value = Value + 1;\r
8d00a0f1 1229\r
1230 //\r
1231 // Suppress <AltResp> if any\r
1232 //\r
1233 StringPtr = Value;\r
1234 while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
1235 StringPtr++;\r
1236 }\r
1237 *StringPtr = L'\0';\r
1238\r
63d55bb9
LG
1239 LengthStr = StrLen (Value);\r
1240 Status = EFI_SUCCESS;\r
7936fb6a 1241 if (!IsBufferStorage && IsString) {\r
1242 //\r
1243 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
63d55bb9 1244 // Add string tail char L'\0' into Length\r
7936fb6a 1245 //\r
63d55bb9
LG
1246 Length = StorageWidth + sizeof (CHAR16);\r
1247 if (Length < ((LengthStr / 4 + 1) * 2)) {\r
1248 Status = EFI_BUFFER_TOO_SMALL;\r
1249 } else {\r
1250 StringPtr = (CHAR16 *) Dst;\r
1251 ZeroMem (TemStr, sizeof (TemStr));\r
1252 for (Index = 0; Index < LengthStr; Index += 4) {\r
1253 StrnCpy (TemStr, Value + Index, 4);\r
1254 StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
1255 }\r
1256 //\r
1257 // Add tailing L'\0' character\r
1258 //\r
1259 StringPtr[Index/4] = L'\0';\r
1260 }\r
7936fb6a 1261 } else {\r
63d55bb9
LG
1262 if (StorageWidth < ((LengthStr + 1) / 2)) {\r
1263 Status = EFI_BUFFER_TOO_SMALL;\r
1264 } else {\r
1265 ZeroMem (TemStr, sizeof (TemStr));\r
1266 for (Index = 0; Index < LengthStr; Index ++) {\r
1267 TemStr[0] = Value[LengthStr - Index - 1];\r
1268 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
1269 if ((Index & 1) == 0) {\r
1270 Dst [Index/2] = DigitUint8;\r
1271 } else {\r
634303c9 1272 Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
63d55bb9
LG
1273 }\r
1274 }\r
7936fb6a 1275 }\r
1276 }\r
1277\r
63d55bb9
LG
1278 if (EFI_ERROR (Status)) {\r
1279 FreePool (Result);\r
1280 return Status;\r
1281 }\r
1282\r
7936fb6a 1283 //\r
1284 // Synchronize Edit Buffer\r
1285 //\r
1286 if (IsBufferStorage) {\r
1287 CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);\r
1288 } else {\r
1289 SetValueByName (Storage, Question->VariableName, Value);\r
1290 }\r
63d55bb9 1291\r
f4113e1f 1292 FreePool (Result);\r
7936fb6a 1293 }\r
1294\r
1295 return Status;\r
1296}\r
1297\r
1298\r
1299/**\r
1300 Save Question Value to edit copy(cached) or Storage(uncached).\r
1301\r
1302 @param FormSet FormSet data structure.\r
1303 @param Form Form data structure.\r
1304 @param Question Pointer to the Question.\r
1305 @param Cached TRUE: set to Edit copy FALSE: set to original\r
1306 Storage\r
1307\r
1308 @retval EFI_SUCCESS The function completed successfully.\r
1309\r
1310**/\r
1311EFI_STATUS\r
1312SetQuestionValue (\r
1313 IN FORM_BROWSER_FORMSET *FormSet,\r
1314 IN FORM_BROWSER_FORM *Form,\r
1315 IN OUT FORM_BROWSER_STATEMENT *Question,\r
1316 IN BOOLEAN Cached\r
1317 )\r
1318{\r
1319 EFI_STATUS Status;\r
1320 BOOLEAN Enabled;\r
1321 BOOLEAN Pending;\r
1322 UINT8 *Src;\r
1323 EFI_TIME EfiTime;\r
1324 UINTN BufferLen;\r
1325 UINTN StorageWidth;\r
1326 FORMSET_STORAGE *Storage;\r
1327 EFI_IFR_TYPE_VALUE *QuestionValue;\r
1328 CHAR16 *ConfigResp;\r
1329 CHAR16 *Progress;\r
1330 CHAR16 *Value;\r
1331 UINTN Length;\r
1332 BOOLEAN IsBufferStorage;\r
1333 BOOLEAN IsString;\r
63d55bb9
LG
1334 UINT8 *TemBuffer;\r
1335 CHAR16 *TemName;\r
1336 CHAR16 *TemString;\r
1337 UINTN Index;\r
7936fb6a 1338\r
1339 Status = EFI_SUCCESS;\r
1340\r
1341 //\r
1342 // Statement don't have storage, skip them\r
1343 //\r
1344 if (Question->QuestionId == 0) {\r
1345 return Status;\r
1346 }\r
1347\r
1348 //\r
1349 // If Question value is provided by an Expression, then it is read only\r
1350 //\r
1351 if (Question->ValueExpression != NULL) {\r
1352 return Status;\r
1353 }\r
1354\r
1355 //\r
1356 // Question value is provided by RTC\r
1357 //\r
1358 Storage = Question->Storage;\r
1359 QuestionValue = &Question->HiiValue.Value;\r
1360 if (Storage == NULL) {\r
1361 //\r
1362 // It's a Question without storage, or RTC date/time\r
1363 //\r
1364 if (Question->Operand == EFI_IFR_DATE_OP || Question->Operand == EFI_IFR_TIME_OP) {\r
1365 //\r
1366 // Date and time define the same Flags bit\r
1367 //\r
1368 switch (Question->Flags & EFI_QF_DATE_STORAGE) {\r
1369 case QF_DATE_STORAGE_TIME:\r
1370 Status = gRT->GetTime (&EfiTime, NULL);\r
1371 break;\r
1372\r
1373 case QF_DATE_STORAGE_WAKEUP:\r
1374 Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);\r
1375 break;\r
1376\r
1377 case QF_DATE_STORAGE_NORMAL:\r
1378 default:\r
1379 //\r
1380 // For date/time without storage\r
1381 //\r
1382 return EFI_SUCCESS;\r
1383 }\r
1384\r
1385 if (EFI_ERROR (Status)) {\r
1386 return Status;\r
1387 }\r
1388\r
1389 if (Question->Operand == EFI_IFR_DATE_OP) {\r
1390 EfiTime.Year = QuestionValue->date.Year;\r
1391 EfiTime.Month = QuestionValue->date.Month;\r
1392 EfiTime.Day = QuestionValue->date.Day;\r
1393 } else {\r
1394 EfiTime.Hour = QuestionValue->time.Hour;\r
1395 EfiTime.Minute = QuestionValue->time.Minute;\r
1396 EfiTime.Second = QuestionValue->time.Second;\r
1397 }\r
1398\r
1399 if ((Question->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_TIME) {\r
1400 Status = gRT->SetTime (&EfiTime);\r
1401 } else {\r
1402 Status = gRT->SetWakeupTime (TRUE, &EfiTime);\r
1403 }\r
1404 }\r
1405\r
1406 return Status;\r
1407 }\r
1408\r
1409 //\r
1410 // Question value is provided by EFI variable\r
1411 //\r
1412 StorageWidth = Question->StorageWidth;\r
1413 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
1414 if (Question->BufferValue != NULL) {\r
1415 Src = Question->BufferValue;\r
1416 } else {\r
1417 Src = (UINT8 *) QuestionValue;\r
1418 }\r
1419\r
1420 Status = gRT->SetVariable (\r
1421 Question->VariableName,\r
1422 &Storage->Guid,\r
1423 Storage->Attributes,\r
1424 StorageWidth,\r
1425 Src\r
1426 );\r
1427 return Status;\r
1428 }\r
1429\r
1430 //\r
1431 // Question Value is provided by Buffer Storage or NameValue Storage\r
1432 //\r
1433 if (Question->BufferValue != NULL) {\r
1434 Src = Question->BufferValue;\r
1435 } else {\r
1436 Src = (UINT8 *) &Question->HiiValue.Value;\r
1437 }\r
1438\r
1439 IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);\r
1440 IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);\r
1441 if (IsBufferStorage) {\r
1442 //\r
1443 // Copy to storage edit buffer\r
1444 //\r
1445 CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
1446 } else {\r
1447 if (IsString) {\r
1448 //\r
63d55bb9 1449 // Allocate enough string buffer.\r
7936fb6a 1450 //\r
1451 Value = NULL;\r
1452 BufferLen = ((StrLen ((CHAR16 *) Src) * 4) + 1) * sizeof (CHAR16);\r
1453 Value = AllocateZeroPool (BufferLen);\r
1454 ASSERT (Value != NULL);\r
63d55bb9
LG
1455 //\r
1456 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
1457 //\r
1458 TemName = (CHAR16 *) Src;\r
1459 TemString = Value;\r
1460 for (; *TemName != L'\0'; TemName++) {\r
1461 TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
1462 }\r
7936fb6a 1463 } else {\r
1464 BufferLen = StorageWidth * 2 + 1;\r
1465 Value = AllocateZeroPool (BufferLen * sizeof (CHAR16));\r
1466 ASSERT (Value != NULL);\r
63d55bb9
LG
1467 //\r
1468 // Convert Buffer to Hex String\r
1469 //\r
1470 TemBuffer = Src + StorageWidth - 1;\r
1471 TemString = Value;\r
1472 for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
1473 TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
1474 }\r
7936fb6a 1475 }\r
1476\r
1477 Status = SetValueByName (Storage, Question->VariableName, Value);\r
f4113e1f 1478 FreePool (Value);\r
7936fb6a 1479 }\r
1480\r
1481 if (!Cached) {\r
1482 //\r
1483 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||\r
1484 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"\r
1485 //\r
1486 if (IsBufferStorage) {\r
1487 Length = StrLen (Question->BlockName) + 7;\r
1488 } else {\r
1489 Length = StrLen (Question->VariableName) + 2;\r
1490 }\r
1491 if (!IsBufferStorage && IsString) {\r
1492 Length += (StrLen ((CHAR16 *) Src) * 4);\r
1493 } else {\r
1494 Length += (StorageWidth * 2);\r
1495 }\r
1496 ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));\r
1497 ASSERT (ConfigResp != NULL);\r
1498\r
1499 StrCpy (ConfigResp, Storage->ConfigHdr);\r
1500 if (IsBufferStorage) {\r
1501 StrCat (ConfigResp, Question->BlockName);\r
1502 StrCat (ConfigResp, L"&VALUE=");\r
1503 } else {\r
1504 StrCat (ConfigResp, L"&");\r
1505 StrCat (ConfigResp, Question->VariableName);\r
1506 StrCat (ConfigResp, L"=");\r
1507 }\r
1508\r
1509 Value = ConfigResp + StrLen (ConfigResp);\r
63d55bb9 1510\r
7936fb6a 1511 if (!IsBufferStorage && IsString) {\r
1512 //\r
1513 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
1514 //\r
63d55bb9
LG
1515 TemName = (CHAR16 *) Src;\r
1516 TemString = Value;\r
1517 for (; *TemName != L'\0'; TemName++) {\r
1518 TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
1519 }\r
7936fb6a 1520 } else {\r
63d55bb9
LG
1521 //\r
1522 // Convert Buffer to Hex String\r
1523 //\r
1524 TemBuffer = Src + StorageWidth - 1;\r
1525 TemString = Value;\r
1526 for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
1527 TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
1528 }\r
1529 }\r
d66e6c16 1530\r
63d55bb9
LG
1531 //\r
1532 // Convert to lower char.\r
1533 //\r
1534 for (TemString = Value; *Value != L'\0'; Value++) {\r
1535 if (*Value >= L'A' && *Value <= L'Z') {\r
1536 *Value = (CHAR16) (*Value - L'A' + L'a');\r
1537 }\r
7936fb6a 1538 }\r
1539\r
1540 //\r
1541 // Submit Question Value to Configuration Driver\r
1542 //\r
1543 if (FormSet->ConfigAccess != NULL) {\r
1544 Status = FormSet->ConfigAccess->RouteConfig (\r
1545 FormSet->ConfigAccess,\r
1546 ConfigResp,\r
1547 &Progress\r
1548 );\r
1549 if (EFI_ERROR (Status)) {\r
f4113e1f 1550 FreePool (ConfigResp);\r
7936fb6a 1551 return Status;\r
1552 }\r
1553 }\r
f4113e1f 1554 FreePool (ConfigResp);\r
7936fb6a 1555\r
1556 //\r
1557 // Synchronize shadow Buffer\r
1558 //\r
1559 SynchronizeStorage (Storage);\r
1560 }\r
1561\r
1562 return Status;\r
1563}\r
1564\r
1565\r
1566/**\r
1567 Perform inconsistent check for a Form.\r
1568\r
1569 @param FormSet FormSet data structure.\r
1570 @param Form Form data structure.\r
1571 @param Question The Question to be validated.\r
1572 @param Type Validation type: InConsistent or NoSubmit\r
1573\r
1574 @retval EFI_SUCCESS Form validation pass.\r
1575 @retval other Form validation failed.\r
1576\r
1577**/\r
1578EFI_STATUS\r
1579ValidateQuestion (\r
1580 IN FORM_BROWSER_FORMSET *FormSet,\r
1581 IN FORM_BROWSER_FORM *Form,\r
1582 IN FORM_BROWSER_STATEMENT *Question,\r
1583 IN UINTN Type\r
1584 )\r
1585{\r
1586 EFI_STATUS Status;\r
1587 LIST_ENTRY *Link;\r
1588 LIST_ENTRY *ListHead;\r
1589 EFI_STRING PopUp;\r
1590 EFI_INPUT_KEY Key;\r
1591 FORM_EXPRESSION *Expression;\r
1592\r
1593 if (Type == EFI_HII_EXPRESSION_INCONSISTENT_IF) {\r
1594 ListHead = &Question->InconsistentListHead;\r
1595 } else if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
1596 ListHead = &Question->NoSubmitListHead;\r
1597 } else {\r
1598 return EFI_UNSUPPORTED;\r
1599 }\r
1600\r
1601 Link = GetFirstNode (ListHead);\r
1602 while (!IsNull (ListHead, Link)) {\r
1603 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
1604\r
1605 //\r
1606 // Evaluate the expression\r
1607 //\r
1608 Status = EvaluateExpression (FormSet, Form, Expression);\r
1609 if (EFI_ERROR (Status)) {\r
1610 return Status;\r
1611 }\r
1612\r
1613 if (Expression->Result.Value.b) {\r
1614 //\r
1615 // Condition meet, show up error message\r
1616 //\r
1617 if (Expression->Error != 0) {\r
1618 PopUp = GetToken (Expression->Error, FormSet->HiiHandle);\r
1619 do {\r
1620 CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, PopUp, gPressEnter, gEmptyString);\r
1621 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
f4113e1f 1622 FreePool (PopUp);\r
7936fb6a 1623 }\r
1624\r
1625 return EFI_NOT_READY;\r
1626 }\r
1627\r
1628 Link = GetNextNode (ListHead, Link);\r
1629 }\r
1630\r
1631 return EFI_SUCCESS;\r
1632}\r
1633\r
1634\r
1635/**\r
1636 Perform NoSubmit check for a Form.\r
1637\r
1638 @param FormSet FormSet data structure.\r
1639 @param Form Form data structure.\r
1640\r
1641 @retval EFI_SUCCESS Form validation pass.\r
1642 @retval other Form validation failed.\r
1643\r
1644**/\r
1645EFI_STATUS\r
1646NoSubmitCheck (\r
1647 IN FORM_BROWSER_FORMSET *FormSet,\r
1648 IN FORM_BROWSER_FORM *Form\r
1649 )\r
1650{\r
1651 EFI_STATUS Status;\r
1652 LIST_ENTRY *Link;\r
1653 FORM_BROWSER_STATEMENT *Question;\r
1654\r
1655 Link = GetFirstNode (&Form->StatementListHead);\r
1656 while (!IsNull (&Form->StatementListHead, Link)) {\r
1657 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1658\r
1659 Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF);\r
1660 if (EFI_ERROR (Status)) {\r
1661 return Status;\r
1662 }\r
1663\r
1664 Link = GetNextNode (&Form->StatementListHead, Link);\r
1665 }\r
1666\r
1667 return EFI_SUCCESS;\r
1668}\r
1669\r
1670\r
1671/**\r
1672 Submit a Form.\r
1673\r
1674 @param FormSet FormSet data structure.\r
1675 @param Form Form data structure.\r
1676\r
1677 @retval EFI_SUCCESS The function completed successfully.\r
1678\r
1679**/\r
1680EFI_STATUS\r
1681SubmitForm (\r
1682 IN FORM_BROWSER_FORMSET *FormSet,\r
1683 IN FORM_BROWSER_FORM *Form\r
1684 )\r
1685{\r
1686 EFI_STATUS Status;\r
1687 LIST_ENTRY *Link;\r
1688 EFI_STRING ConfigResp;\r
1689 EFI_STRING Progress;\r
1690 FORMSET_STORAGE *Storage;\r
1691\r
1692 //\r
1693 // Validate the Form by NoSubmit check\r
1694 //\r
1695 Status = NoSubmitCheck (FormSet, Form);\r
1696 if (EFI_ERROR (Status)) {\r
1697 return Status;\r
1698 }\r
1699\r
1700 //\r
1701 // Submit Buffer storage or Name/Value storage\r
1702 //\r
1703 Link = GetFirstNode (&FormSet->StorageListHead);\r
1704 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
1705 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
1706 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
1707\r
1708 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
1709 continue;\r
1710 }\r
1711\r
1712 //\r
1713 // Skip if there is no RequestElement\r
1714 //\r
1715 if (Storage->ElementCount == 0) {\r
1716 continue;\r
1717 }\r
1718\r
1719 //\r
1720 // Prepare <ConfigResp>\r
1721 //\r
1722 Status = StorageToConfigResp (Storage, &ConfigResp);\r
1723 if (EFI_ERROR (Status)) {\r
1724 return Status;\r
1725 }\r
1726\r
1727 //\r
1728 // Send <ConfigResp> to Configuration Driver\r
1729 //\r
1730 if (FormSet->ConfigAccess != NULL) {\r
1731 Status = FormSet->ConfigAccess->RouteConfig (\r
1732 FormSet->ConfigAccess,\r
1733 ConfigResp,\r
1734 &Progress\r
1735 );\r
1736 if (EFI_ERROR (Status)) {\r
f4113e1f 1737 FreePool (ConfigResp);\r
7936fb6a 1738 return Status;\r
1739 }\r
1740 }\r
f4113e1f 1741 FreePool (ConfigResp);\r
7936fb6a 1742\r
1743 //\r
1744 // Config success, update storage shadow Buffer\r
1745 //\r
1746 SynchronizeStorage (Storage);\r
1747 }\r
1748\r
1749 gNvUpdateRequired = FALSE;\r
1750\r
1751 return EFI_SUCCESS;\r
1752}\r
1753\r
1754\r
1755/**\r
1756 Reset Question to its default value.\r
1757\r
1758 @param FormSet The form set.\r
1759 @param Form The form.\r
1760 @param Question The question.\r
1761 @param DefaultId The Class of the default.\r
1762\r
1763 @retval EFI_SUCCESS Question is reset to default value.\r
1764\r
1765**/\r
1766EFI_STATUS\r
1767GetQuestionDefault (\r
1768 IN FORM_BROWSER_FORMSET *FormSet,\r
1769 IN FORM_BROWSER_FORM *Form,\r
1770 IN FORM_BROWSER_STATEMENT *Question,\r
1771 IN UINT16 DefaultId\r
1772 )\r
1773{\r
1774 EFI_STATUS Status;\r
1775 LIST_ENTRY *Link;\r
1776 QUESTION_DEFAULT *Default;\r
1777 QUESTION_OPTION *Option;\r
1778 EFI_HII_VALUE *HiiValue;\r
1779 UINT8 Index;\r
086cd2c8 1780 EFI_STRING StrValue;\r
7936fb6a 1781\r
086cd2c8
LG
1782 Status = EFI_SUCCESS;\r
1783 StrValue = NULL;\r
7936fb6a 1784\r
1785 //\r
1786 // Statement don't have storage, skip them\r
1787 //\r
1788 if (Question->QuestionId == 0) {\r
1789 return Status;\r
1790 }\r
1791\r
1792 //\r
1793 // There are three ways to specify default value for a Question:\r
1794 // 1, use nested EFI_IFR_DEFAULT (highest priority)\r
1795 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
1796 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
1797 //\r
1798 HiiValue = &Question->HiiValue;\r
1799\r
1800 //\r
1801 // EFI_IFR_DEFAULT has highest priority\r
1802 //\r
1803 if (!IsListEmpty (&Question->DefaultListHead)) {\r
1804 Link = GetFirstNode (&Question->DefaultListHead);\r
1805 while (!IsNull (&Question->DefaultListHead, Link)) {\r
1806 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
1807\r
1808 if (Default->DefaultId == DefaultId) {\r
1809 if (Default->ValueExpression != NULL) {\r
1810 //\r
1811 // Default is provided by an Expression, evaluate it\r
1812 //\r
1813 Status = EvaluateExpression (FormSet, Form, Default->ValueExpression);\r
1814 if (EFI_ERROR (Status)) {\r
1815 return Status;\r
1816 }\r
1817\r
1818 CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE));\r
1819 } else {\r
1820 //\r
1821 // Default value is embedded in EFI_IFR_DEFAULT\r
1822 //\r
1823 CopyMem (HiiValue, &Default->Value, sizeof (EFI_HII_VALUE));\r
1824 }\r
1825\r
086cd2c8
LG
1826 if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
1827 StrValue = HiiGetString (FormSet->HiiHandle, HiiValue->Value.string, NULL);\r
1828 if (StrValue == NULL) {\r
1829 return EFI_NOT_FOUND;\r
1830 }\r
1831 Question->BufferValue = AllocateCopyPool (StrSize (StrValue), StrValue);\r
1832 }\r
1833\r
7936fb6a 1834 return EFI_SUCCESS;\r
1835 }\r
1836\r
1837 Link = GetNextNode (&Question->DefaultListHead, Link);\r
1838 }\r
1839 }\r
1840\r
1841 //\r
1842 // EFI_ONE_OF_OPTION\r
1843 //\r
1844 if ((Question->Operand == EFI_IFR_ONE_OF_OP) && !IsListEmpty (&Question->OptionListHead)) {\r
1845 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
1846 //\r
1847 // OneOfOption could only provide Standard and Manufacturing default\r
1848 //\r
1849 Link = GetFirstNode (&Question->OptionListHead);\r
1850 while (!IsNull (&Question->OptionListHead, Link)) {\r
1851 Option = QUESTION_OPTION_FROM_LINK (Link);\r
1852\r
1853 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT) != 0)) ||\r
1854 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Option->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0))\r
1855 ) {\r
1856 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
1857\r
1858 return EFI_SUCCESS;\r
1859 }\r
1860\r
1861 Link = GetNextNode (&Question->OptionListHead, Link);\r
1862 }\r
1863 }\r
1864 }\r
1865\r
1866 //\r
1867 // EFI_IFR_CHECKBOX - lowest priority\r
1868 //\r
1869 if (Question->Operand == EFI_IFR_CHECKBOX_OP) {\r
1870 if (DefaultId <= EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
1871 //\r
1872 // Checkbox could only provide Standard and Manufacturing default\r
1873 //\r
1874 if (((DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0)) ||\r
1875 ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))\r
1876 ) {\r
1877 HiiValue->Value.b = TRUE;\r
1878 } else {\r
1879 HiiValue->Value.b = FALSE;\r
1880 }\r
1881\r
1882 return EFI_SUCCESS;\r
1883 }\r
1884 }\r
1885\r
1886 //\r
1887 // For Questions without default\r
1888 //\r
1889 switch (Question->Operand) {\r
7936fb6a 1890 case EFI_IFR_ONE_OF_OP:\r
1891 //\r
1892 // Take first oneof option as oneof's default value\r
1893 //\r
d66e6c16 1894 if (ValueToOption (Question, HiiValue) == NULL) {\r
0a1147ed
LG
1895 Link = GetFirstNode (&Question->OptionListHead);\r
1896 if (!IsNull (&Question->OptionListHead, Link)) {\r
1897 Option = QUESTION_OPTION_FROM_LINK (Link);\r
1898 CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
1899 }\r
7936fb6a 1900 }\r
1901 break;\r
1902\r
1903 case EFI_IFR_ORDERED_LIST_OP:\r
1904 //\r
1905 // Take option sequence in IFR as ordered list's default value\r
1906 //\r
1907 Index = 0;\r
1908 Link = GetFirstNode (&Question->OptionListHead);\r
1909 while (!IsNull (&Question->OptionListHead, Link)) {\r
1910 Option = QUESTION_OPTION_FROM_LINK (Link);\r
1911\r
1912 Question->BufferValue[Index] = Option->Value.Value.u8;\r
1913\r
1914 Index++;\r
1915 if (Index >= Question->MaxContainers) {\r
1916 break;\r
1917 }\r
1918\r
1919 Link = GetNextNode (&Question->OptionListHead, Link);\r
1920 }\r
1921 break;\r
1922\r
1923 default:\r
1924 Status = EFI_NOT_FOUND;\r
1925 break;\r
1926 }\r
1927\r
1928 return Status;\r
1929}\r
1930\r
1931\r
1932/**\r
1933 Reset Questions in a Form to their default value.\r
1934\r
1935 @param FormSet FormSet data structure.\r
1936 @param Form The Form which to be reset.\r
1937 @param DefaultId The Class of the default.\r
1938\r
1939 @retval EFI_SUCCESS The function completed successfully.\r
1940\r
1941**/\r
1942EFI_STATUS\r
1943ExtractFormDefault (\r
1944 IN FORM_BROWSER_FORMSET *FormSet,\r
1945 IN FORM_BROWSER_FORM *Form,\r
1946 IN UINT16 DefaultId\r
1947 )\r
1948{\r
1949 EFI_STATUS Status;\r
1950 LIST_ENTRY *Link;\r
1951 FORM_BROWSER_STATEMENT *Question;\r
1952\r
1953 Link = GetFirstNode (&Form->StatementListHead);\r
1954 while (!IsNull (&Form->StatementListHead, Link)) {\r
1955 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
1956 Link = GetNextNode (&Form->StatementListHead, Link);\r
1957\r
8d00a0f1 1958 //\r
0a1147ed 1959 // If Question is disabled, don't reset it to default\r
8d00a0f1 1960 //\r
0a1147ed
LG
1961 if (Question->DisableExpression != NULL) {\r
1962 Status = EvaluateExpression (FormSet, Form, Question->DisableExpression);\r
1963 if (!EFI_ERROR (Status) && Question->DisableExpression->Result.Value.b) {\r
8d00a0f1 1964 continue;\r
1965 }\r
1966 }\r
1967\r
7936fb6a 1968 //\r
1969 // Reset Question to its default value\r
1970 //\r
1971 Status = GetQuestionDefault (FormSet, Form, Question, DefaultId);\r
1972 if (EFI_ERROR (Status)) {\r
1973 continue;\r
1974 }\r
1975\r
1976 //\r
1977 // Synchronize Buffer storage's Edit buffer\r
1978 //\r
1979 if ((Question->Storage != NULL) &&\r
1980 (Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
1981 SetQuestionValue (FormSet, Form, Question, TRUE);\r
1982 }\r
1983 }\r
1984\r
1985 return EFI_SUCCESS;\r
1986}\r
1987\r
1988\r
1989/**\r
1990 Initialize Question's Edit copy from Storage.\r
1991\r
1992 @param FormSet FormSet data structure.\r
1993 @param Form Form data structure.\r
1994\r
1995 @retval EFI_SUCCESS The function completed successfully.\r
1996\r
1997**/\r
1998EFI_STATUS\r
1999LoadFormConfig (\r
2000 IN FORM_BROWSER_FORMSET *FormSet,\r
2001 IN FORM_BROWSER_FORM *Form\r
2002 )\r
2003{\r
2004 EFI_STATUS Status;\r
2005 LIST_ENTRY *Link;\r
2006 FORM_BROWSER_STATEMENT *Question;\r
2007\r
2008 Link = GetFirstNode (&Form->StatementListHead);\r
2009 while (!IsNull (&Form->StatementListHead, Link)) {\r
2010 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
2011\r
2012 //\r
2013 // Initialize local copy of Value for each Question\r
2014 //\r
2015 Status = GetQuestionValue (FormSet, Form, Question, TRUE);\r
2016 if (EFI_ERROR (Status)) {\r
2017 return Status;\r
2018 }\r
2019\r
2020 Link = GetNextNode (&Form->StatementListHead, Link);\r
2021 }\r
2022\r
2023 return EFI_SUCCESS;\r
2024}\r
2025\r
2026\r
d66e6c16 2027/**\r
2028 Initialize Question's Edit copy from Storage for the whole Formset.\r
2029\r
2030 @param FormSet FormSet data structure.\r
2031\r
2032 @retval EFI_SUCCESS The function completed successfully.\r
2033\r
2034**/\r
2035EFI_STATUS\r
2036LoadFormSetConfig (\r
2037 IN FORM_BROWSER_FORMSET *FormSet\r
2038 )\r
2039{\r
2040 EFI_STATUS Status;\r
2041 LIST_ENTRY *Link;\r
2042 FORM_BROWSER_FORM *Form;\r
2043\r
2044 Link = GetFirstNode (&FormSet->FormListHead);\r
2045 while (!IsNull (&FormSet->FormListHead, Link)) {\r
2046 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
2047\r
2048 //\r
2049 // Initialize local copy of Value for each Form\r
2050 //\r
2051 Status = LoadFormConfig (FormSet, Form);\r
2052 if (EFI_ERROR (Status)) {\r
2053 return Status;\r
2054 }\r
2055\r
2056 Link = GetNextNode (&FormSet->FormListHead, Link);\r
2057 }\r
2058\r
2059 return EFI_SUCCESS;\r
2060}\r
2061\r
2062\r
7936fb6a 2063/**\r
2064 Fill storage's edit copy with settings requested from Configuration Driver.\r
2065\r
2066 @param FormSet FormSet data structure.\r
2067 @param Storage Buffer Storage.\r
2068\r
2069 @retval EFI_SUCCESS The function completed successfully.\r
2070\r
2071**/\r
2072EFI_STATUS\r
2073LoadStorage (\r
2074 IN FORM_BROWSER_FORMSET *FormSet,\r
2075 IN FORMSET_STORAGE *Storage\r
2076 )\r
2077{\r
2078 EFI_STATUS Status;\r
2079 EFI_STRING Progress;\r
2080 EFI_STRING Result;\r
2081 CHAR16 *StrPtr;\r
2082\r
2083 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
2084 return EFI_SUCCESS;\r
2085 }\r
2086\r
2087 if (FormSet->ConfigAccess == NULL) {\r
2088 return EFI_NOT_FOUND;\r
2089 }\r
2090\r
2091 if (Storage->ElementCount == 0) {\r
2092 //\r
2093 // Skip if there is no RequestElement\r
2094 //\r
2095 return EFI_SUCCESS;\r
2096 }\r
2097\r
2098 //\r
2099 // Request current settings from Configuration Driver\r
2100 //\r
2101 Status = FormSet->ConfigAccess->ExtractConfig (\r
2102 FormSet->ConfigAccess,\r
2103 Storage->ConfigRequest,\r
2104 &Progress,\r
2105 &Result\r
2106 );\r
2107 if (EFI_ERROR (Status)) {\r
2108 return Status;\r
2109 }\r
2110\r
2111 //\r
2112 // Convert Result from <ConfigAltResp> to <ConfigResp>\r
2113 //\r
2114 StrPtr = StrStr (Result, L"ALTCFG");\r
2115 if (StrPtr != NULL) {\r
2116 *StrPtr = L'\0';\r
2117 }\r
2118\r
2119 Status = ConfigRespToStorage (Storage, Result);\r
f4113e1f 2120 FreePool (Result);\r
7936fb6a 2121 return Status;\r
2122}\r
2123\r
2124\r
d66e6c16 2125/**\r
2126 Copy uncommitted data from source Storage to destination Storage.\r
2127\r
2128 @param Dst Target Storage for uncommitted data.\r
2129 @param Src Source Storage for uncommitted data.\r
2130\r
2131 @retval EFI_SUCCESS The function completed successfully.\r
2132 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.\r
2133\r
2134**/\r
2135EFI_STATUS\r
2136CopyStorage (\r
2137 IN OUT FORMSET_STORAGE *Dst,\r
2138 IN FORMSET_STORAGE *Src\r
2139 )\r
2140{\r
2141 LIST_ENTRY *Link;\r
2142 NAME_VALUE_NODE *Node;\r
2143\r
2144 if ((Dst->Type != Src->Type) || (Dst->Size != Src->Size)) {\r
2145 return EFI_INVALID_PARAMETER;\r
2146 }\r
2147\r
2148 switch (Src->Type) {\r
2149 case EFI_HII_VARSTORE_BUFFER:\r
2150 CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size);\r
2151 break;\r
2152\r
2153 case EFI_HII_VARSTORE_NAME_VALUE:\r
2154 Link = GetFirstNode (&Src->NameValueListHead);\r
2155 while (!IsNull (&Src->NameValueListHead, Link)) {\r
2156 Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
2157\r
2158 SetValueByName (Dst, Node->Name, Node->EditValue);\r
2159\r
2160 Link = GetNextNode (&Src->NameValueListHead, Link);\r
2161 }\r
2162 break;\r
2163\r
2164 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
2165 default:\r
2166 break;\r
2167 }\r
2168\r
2169 return EFI_SUCCESS;\r
2170}\r
2171\r
2172\r
7936fb6a 2173/**\r
2174 Get current setting of Questions.\r
2175\r
2176 @param FormSet FormSet data structure.\r
2177\r
2178 @retval EFI_SUCCESS The function completed successfully.\r
2179\r
2180**/\r
2181EFI_STATUS\r
2182InitializeCurrentSetting (\r
2183 IN OUT FORM_BROWSER_FORMSET *FormSet\r
2184 )\r
2185{\r
2186 LIST_ENTRY *Link;\r
d66e6c16 2187 LIST_ENTRY *Link2;\r
7936fb6a 2188 FORMSET_STORAGE *Storage;\r
d66e6c16 2189 FORMSET_STORAGE *StorageSrc;\r
2190 FORMSET_STORAGE *OldStorage;\r
7936fb6a 2191 FORM_BROWSER_FORM *Form;\r
2192 EFI_STATUS Status;\r
2193\r
2194 //\r
2195 // Extract default from IFR binary\r
2196 //\r
2197 Link = GetFirstNode (&FormSet->FormListHead);\r
2198 while (!IsNull (&FormSet->FormListHead, Link)) {\r
2199 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
2200\r
2201 Status = ExtractFormDefault (FormSet, Form, EFI_HII_DEFAULT_CLASS_STANDARD);\r
2202\r
2203 Link = GetNextNode (&FormSet->FormListHead, Link);\r
2204 }\r
2205\r
2206 //\r
2207 // Request current settings from Configuration Driver\r
2208 //\r
2209 Link = GetFirstNode (&FormSet->StorageListHead);\r
2210 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
2211 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
2212\r
d66e6c16 2213 OldStorage = NULL;\r
2214 if (gOldFormSet != NULL) {\r
2215 //\r
2216 // Try to find the Storage in backup formset gOldFormSet\r
2217 //\r
2218 Link2 = GetFirstNode (&gOldFormSet->StorageListHead);\r
2219 while (!IsNull (&gOldFormSet->StorageListHead, Link2)) {\r
2220 StorageSrc = FORMSET_STORAGE_FROM_LINK (Link2);\r
2221\r
2222 if (StorageSrc->VarStoreId == Storage->VarStoreId) {\r
2223 OldStorage = StorageSrc;\r
2224 break;\r
2225 }\r
2226\r
2227 Link2 = GetNextNode (&gOldFormSet->StorageListHead, Link2);\r
2228 }\r
2229 }\r
2230\r
2231 if (OldStorage == NULL) {\r
2232 //\r
2233 // Storage is not found in backup formset, request it from ConfigDriver\r
2234 //\r
2235 Status = LoadStorage (FormSet, Storage);\r
2236 } else {\r
2237 //\r
2238 // Storage found in backup formset, use it\r
2239 //\r
2240 Status = CopyStorage (Storage, OldStorage);\r
2241 }\r
7936fb6a 2242\r
2243 //\r
2244 // Now Edit Buffer is filled with default values(lower priority) and current\r
2245 // settings(higher priority), sychronize it to shadow Buffer\r
2246 //\r
2247 if (!EFI_ERROR (Status)) {\r
2248 SynchronizeStorage (Storage);\r
2249 }\r
2250\r
2251 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
2252 }\r
2253\r
2254 return EFI_SUCCESS;\r
2255}\r
2256\r
2257\r
2258/**\r
2259 Fetch the Ifr binary data of a FormSet.\r
2260\r
2261 @param Handle PackageList Handle\r
2262 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
2263 GUID), take the first FormSet found in package\r
2264 list.\r
2265 @param BinaryLength The length of the FormSet IFR binary.\r
2266 @param BinaryData The buffer designed to receive the FormSet.\r
2267\r
2268 @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
2269 BufferLength was updated.\r
2270 @retval EFI_INVALID_PARAMETER The handle is unknown.\r
2271 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
2272 be found with the requested FormId.\r
2273\r
2274**/\r
2275EFI_STATUS\r
2276GetIfrBinaryData (\r
2277 IN EFI_HII_HANDLE Handle,\r
2278 IN OUT EFI_GUID *FormSetGuid,\r
2279 OUT UINTN *BinaryLength,\r
2280 OUT UINT8 **BinaryData\r
2281 )\r
2282{\r
2283 EFI_STATUS Status;\r
2284 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
2285 UINTN BufferSize;\r
2286 UINT8 *Package;\r
2287 UINT8 *OpCodeData;\r
2288 UINT32 Offset;\r
2289 UINT32 Offset2;\r
2290 BOOLEAN ReturnDefault;\r
2291 UINT32 PackageListLength;\r
2292 EFI_HII_PACKAGE_HEADER PackageHeader;\r
0a1147ed
LG
2293 UINT8 Index;\r
2294 UINT8 NumberOfClassGuid;\r
2295 BOOLEAN IsSetupClassGuid;\r
2296 EFI_GUID *ClassGuid;\r
7936fb6a 2297\r
2298 OpCodeData = NULL;\r
2299 Package = NULL;\r
2300 ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
2301\r
2302 //\r
2303 // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
2304 //\r
2305 if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
2306 ReturnDefault = TRUE;\r
2307 } else {\r
2308 ReturnDefault = FALSE;\r
2309 }\r
2310\r
2311 //\r
2312 // Get HII PackageList\r
2313 //\r
2314 BufferSize = 0;\r
2315 HiiPackageList = NULL;\r
2316 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
2317 if (Status == EFI_BUFFER_TOO_SMALL) {\r
2318 HiiPackageList = AllocatePool (BufferSize);\r
2319 ASSERT (HiiPackageList != NULL);\r
2320\r
2321 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
2322 }\r
2323 if (EFI_ERROR (Status)) {\r
2324 return Status;\r
2325 }\r
db0bd81c 2326 ASSERT (HiiPackageList != NULL);\r
d66e6c16 2327\r
7936fb6a 2328 //\r
2329 // Get Form package from this HII package List\r
2330 //\r
2331 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
2332 Offset2 = 0;\r
2333 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
2334\r
2335 while (Offset < PackageListLength) {\r
2336 Package = ((UINT8 *) HiiPackageList) + Offset;\r
2337 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
2338\r
8d00a0f1 2339 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
7936fb6a 2340 //\r
2341 // Search FormSet in this Form Package\r
2342 //\r
2343 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
2344 while (Offset2 < PackageHeader.Length) {\r
2345 OpCodeData = Package + Offset2;\r
2346\r
2347 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
2348 //\r
2349 // Check whether return default FormSet\r
2350 //\r
2351 if (ReturnDefault) {\r
0a1147ed
LG
2352 //\r
2353 // Check ClassGuid of formset OpCode\r
2354 //\r
2355 IsSetupClassGuid = FALSE;\r
7da73676 2356 NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
0a1147ed
LG
2357 ClassGuid = (EFI_GUID *) (OpCodeData + sizeof (EFI_IFR_FORM_SET));\r
2358 for (Index = 0; Index < NumberOfClassGuid; Index++) {\r
2359 if (CompareGuid (ClassGuid + Index, &gEfiHiiPlatformSetupFormsetGuid)) {\r
2360 IsSetupClassGuid = TRUE;\r
2361 break;\r
2362 }\r
2363 }\r
2364 if (IsSetupClassGuid) {\r
2365 break;\r
2366 }\r
7936fb6a 2367 }\r
2368\r
2369 //\r
2370 // FormSet GUID is specified, check it\r
2371 //\r
2372 if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
2373 break;\r
2374 }\r
2375 }\r
2376\r
2377 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
2378 }\r
2379\r
2380 if (Offset2 < PackageHeader.Length) {\r
2381 //\r
2382 // Target formset found\r
2383 //\r
2384 break;\r
2385 }\r
2386 }\r
2387\r
2388 Offset += PackageHeader.Length;\r
2389 }\r
2390\r
2391 if (Offset >= PackageListLength) {\r
2392 //\r
2393 // Form package not found in this Package List\r
2394 //\r
f4113e1f 2395 FreePool (HiiPackageList);\r
7936fb6a 2396 return EFI_NOT_FOUND;\r
2397 }\r
2398\r
2399 if (ReturnDefault && FormSetGuid != NULL) {\r
2400 //\r
2401 // Return the default FormSet GUID\r
2402 //\r
2403 CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
2404 }\r
2405\r
2406 //\r
2407 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
2408 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
2409 // of the Form Package.\r
2410 //\r
2411 *BinaryLength = PackageHeader.Length - Offset2;\r
2412 *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
2413\r
f4113e1f 2414 FreePool (HiiPackageList);\r
7936fb6a 2415\r
2416 if (*BinaryData == NULL) {\r
2417 return EFI_OUT_OF_RESOURCES;\r
2418 }\r
2419\r
2420 return EFI_SUCCESS;\r
2421}\r
2422\r
2423\r
2424/**\r
2425 Initialize the internal data structure of a FormSet.\r
2426\r
2427 @param Handle PackageList Handle\r
2428 @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
2429 GUID), take the first FormSet found in package\r
2430 list.\r
2431 @param FormSet FormSet data structure.\r
2432\r
2433 @retval EFI_SUCCESS The function completed successfully.\r
2434 @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
2435\r
2436**/\r
2437EFI_STATUS\r
2438InitializeFormSet (\r
2439 IN EFI_HII_HANDLE Handle,\r
2440 IN OUT EFI_GUID *FormSetGuid,\r
2441 OUT FORM_BROWSER_FORMSET *FormSet\r
2442 )\r
2443{\r
2444 EFI_STATUS Status;\r
2445 EFI_HANDLE DriverHandle;\r
2446 UINT16 Index;\r
2447\r
2448 Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
2449 if (EFI_ERROR (Status)) {\r
2450 return Status;\r
2451 }\r
2452\r
2453 FormSet->HiiHandle = Handle;\r
2454 CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
2455\r
2456 //\r
2457 // Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
2458 //\r
2459 Status = mHiiDatabase->GetPackageListHandle (mHiiDatabase, Handle, &DriverHandle);\r
2460 if (EFI_ERROR (Status)) {\r
2461 return Status;\r
2462 }\r
2463 FormSet->DriverHandle = DriverHandle;\r
2464 Status = gBS->HandleProtocol (\r
2465 DriverHandle,\r
2466 &gEfiHiiConfigAccessProtocolGuid,\r
2467 (VOID **) &FormSet->ConfigAccess\r
2468 );\r
2469 if (EFI_ERROR (Status)) {\r
2470 //\r
2471 // Configuration Driver don't attach ConfigAccess protocol to its HII package\r
2472 // list, then there will be no configuration action required\r
2473 //\r
2474 FormSet->ConfigAccess = NULL;\r
2475 }\r
2476\r
2477 //\r
2478 // Parse the IFR binary OpCodes\r
2479 //\r
2480 Status = ParseOpCodes (FormSet);\r
2481 if (EFI_ERROR (Status)) {\r
2482 return Status;\r
2483 }\r
2484\r
0a1147ed
LG
2485 gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;\r
2486 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
2487 gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;\r
2488 gFrontPageHandle = FormSet->HiiHandle;\r
7936fb6a 2489 }\r
2490\r
2491 //\r
2492 // Match GUID to find out the function key setting. If match fail, use the default setting.\r
2493 //\r
2494 for (Index = 0; Index < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index++) {\r
2495 if (CompareGuid (&FormSet->Guid, &(gFunctionKeySettingTable[Index].FormSetGuid))) {\r
2496 //\r
2497 // Update the function key setting.\r
2498 //\r
2499 gFunctionKeySetting = gFunctionKeySettingTable[Index].KeySetting;\r
2500 //\r
2501 // Function key prompt can not be displayed if the function key has been disabled.\r
2502 //\r
2503 if ((gFunctionKeySetting & FUNCTION_ONE) != FUNCTION_ONE) {\r
2504 gFunctionOneString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
2505 }\r
2506\r
7936fb6a 2507 if ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE) {\r
2508 gFunctionNineString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
2509 }\r
2510\r
2511 if ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN) {\r
2512 gFunctionTenString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
2513 }\r
2514 }\r
2515 }\r
2516\r
2517 return Status;\r
2518}\r