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