2 Entry and initialization module for the browser.
4 Copyright (c) 2007 - 2010, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 SETUP_DRIVER_PRIVATE_DATA mPrivateData
= {
18 SETUP_DRIVER_SIGNATURE
,
26 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
27 EFI_HII_STRING_PROTOCOL
*mHiiString
;
28 EFI_HII_CONFIG_ROUTING_PROTOCOL
*mHiiConfigRouting
;
30 UINTN gBrowserContextCount
= 0;
31 LIST_ENTRY gBrowserContextList
= INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList
);
33 BANNER_DATA
*gBannerData
;
34 EFI_HII_HANDLE gFrontPageHandle
;
36 UINTN gFunctionKeySetting
;
37 BOOLEAN gResetRequired
;
38 BOOLEAN gNvUpdateRequired
;
39 EFI_HII_HANDLE gHiiHandle
;
41 EFI_SCREEN_DESCRIPTOR gScreenDimensions
;
44 // Browser Global Strings
46 CHAR16
*gFunctionNineString
;
47 CHAR16
*gFunctionTenString
;
49 CHAR16
*gEnterCommitString
;
50 CHAR16
*gEnterEscapeString
;
51 CHAR16
*gEscapeString
;
53 CHAR16
*gMoveHighlight
;
54 CHAR16
*gMakeSelection
;
55 CHAR16
*gDecNumericInput
;
56 CHAR16
*gHexNumericInput
;
57 CHAR16
*gToggleCheckBox
;
58 CHAR16
*gPromptForData
;
59 CHAR16
*gPromptForPassword
;
60 CHAR16
*gPromptForNewPassword
;
61 CHAR16
*gConfirmPassword
;
62 CHAR16
*gConfirmError
;
63 CHAR16
*gPassowordInvalid
;
72 CHAR16
*gAdjustNumber
;
74 CHAR16
*gOptionMismatch
;
75 CHAR16
*gFormSuppress
;
77 CHAR16
*mUnknownString
= L
"!";
79 CHAR16 gPromptBlockWidth
;
80 CHAR16 gOptionBlockWidth
;
81 CHAR16 gHelpBlockWidth
;
83 EFI_GUID gZeroGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
84 EFI_GUID gSetupBrowserGuid
= {
85 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
88 FORM_BROWSER_FORMSET
*gOldFormSet
;
90 FUNCTIION_KEY_SETTING gFunctionKeySettingTable
[] = {
110 NONE_FUNCTION_KEY_SETTING
131 NONE_FUNCTION_KEY_SETTING
152 NONE_FUNCTION_KEY_SETTING
155 // BMM File Explorer FormSet.
173 NONE_FUNCTION_KEY_SETTING
178 This is the routine which an external caller uses to direct the browser
179 where to obtain it's information.
182 @param This The Form Browser protocol instanse.
183 @param Handles A pointer to an array of Handles. If HandleCount > 1 we
184 display a list of the formsets for the handles specified.
185 @param HandleCount The number of Handles specified in Handle.
186 @param FormSetGuid This field points to the EFI_GUID which must match the Guid
187 field in the EFI_IFR_FORM_SET op-code for the specified
188 forms-based package. If FormSetGuid is NULL, then this
189 function will display the first found forms package.
190 @param FormId This field specifies which EFI_IFR_FORM to render as the first
191 displayable page. If this field has a value of 0x0000, then
192 the forms browser will render the specified forms in their encoded order.
193 @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in
195 @param ActionRequest Points to the action recommended by the form.
197 @retval EFI_SUCCESS The function completed successfully.
198 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
199 @retval EFI_NOT_FOUND No valid forms could be found to display.
205 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
206 IN EFI_HII_HANDLE
*Handles
,
207 IN UINTN HandleCount
,
208 IN EFI_GUID
*FormSetGuid
, OPTIONAL
209 IN UINT16 FormId
, OPTIONAL
210 IN CONST EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
211 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest OPTIONAL
215 UI_MENU_SELECTION
*Selection
;
217 FORM_BROWSER_FORMSET
*FormSet
;
220 // Save globals used by SendForm()
222 SaveBrowserContext ();
224 Status
= EFI_SUCCESS
;
225 ZeroMem (&gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
228 // Seed the dimensions in the global
230 gST
->ConOut
->QueryMode (
232 gST
->ConOut
->Mode
->Mode
,
233 &gScreenDimensions
.RightColumn
,
234 &gScreenDimensions
.BottomRow
237 if (ScreenDimensions
!= NULL
) {
239 // Check local dimension vs. global dimension.
241 if ((gScreenDimensions
.RightColumn
< ScreenDimensions
->RightColumn
) ||
242 (gScreenDimensions
.BottomRow
< ScreenDimensions
->BottomRow
)
244 Status
= EFI_INVALID_PARAMETER
;
248 // Local dimension validation.
250 if ((ScreenDimensions
->RightColumn
> ScreenDimensions
->LeftColumn
) &&
251 (ScreenDimensions
->BottomRow
> ScreenDimensions
->TopRow
) &&
252 ((ScreenDimensions
->RightColumn
- ScreenDimensions
->LeftColumn
) > 2) &&
254 (ScreenDimensions
->BottomRow
- ScreenDimensions
->TopRow
) > STATUS_BAR_HEIGHT
+
255 SCROLL_ARROW_HEIGHT
*
257 FRONT_PAGE_HEADER_HEIGHT
+
262 CopyMem (&gScreenDimensions
, (VOID
*) ScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
264 Status
= EFI_INVALID_PARAMETER
;
270 gOptionBlockWidth
= (CHAR16
) ((gScreenDimensions
.RightColumn
- gScreenDimensions
.LeftColumn
) / 3);
271 gHelpBlockWidth
= gOptionBlockWidth
;
272 gPromptBlockWidth
= gOptionBlockWidth
;
275 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
277 InitializeBrowserStrings ();
279 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
282 // Ensure we are in Text mode
284 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
286 for (Index
= 0; Index
< HandleCount
; Index
++) {
287 Selection
= AllocateZeroPool (sizeof (UI_MENU_SELECTION
));
288 ASSERT (Selection
!= NULL
);
290 Selection
->Handle
= Handles
[Index
];
291 if (FormSetGuid
!= NULL
) {
292 CopyMem (&Selection
->FormSetGuid
, FormSetGuid
, sizeof (EFI_GUID
));
293 Selection
->FormId
= FormId
;
297 gNvUpdateRequired
= FALSE
;
300 FormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
301 ASSERT (FormSet
!= NULL
);
304 // Initialize internal data structures of FormSet
306 Status
= InitializeFormSet (Selection
->Handle
, &Selection
->FormSetGuid
, FormSet
);
307 if (EFI_ERROR (Status
) || IsListEmpty (&FormSet
->FormListHead
)) {
308 DestroyFormSet (FormSet
);
311 Selection
->FormSet
= FormSet
;
314 // Display this formset
316 gCurrentSelection
= Selection
;
318 Status
= SetupBrowser (Selection
);
320 gCurrentSelection
= NULL
;
322 if (EFI_ERROR (Status
)) {
326 } while (Selection
->Action
== UI_ACTION_REFRESH_FORMSET
);
328 if (gOldFormSet
!= NULL
) {
329 DestroyFormSet (gOldFormSet
);
333 FreePool (Selection
);
336 if (ActionRequest
!= NULL
) {
337 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
338 if (gResetRequired
) {
339 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
343 FreeBrowserStrings ();
345 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
346 gST
->ConOut
->ClearScreen (gST
->ConOut
);
350 // Restore globals used by SendForm()
352 RestoreBrowserContext ();
359 This function is called by a callback handler to retrieve uncommitted state
360 data from the browser.
362 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
364 @param ResultsDataSize A pointer to the size of the buffer associated
366 @param ResultsData A string returned from an IFR browser or
367 equivalent. The results string will have no
368 routing information in them.
369 @param RetrieveData A BOOLEAN field which allows an agent to retrieve
370 (if RetrieveData = TRUE) data from the uncommitted
371 browser state information or set (if RetrieveData
372 = FALSE) data in the uncommitted browser state
374 @param VariableGuid An optional field to indicate the target variable
376 @param VariableName An optional field to indicate the target
377 human-readable variable name.
379 @retval EFI_SUCCESS The results have been distributed or are awaiting
381 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to
382 contain the results data.
388 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
389 IN OUT UINTN
*ResultsDataSize
,
390 IN OUT EFI_STRING ResultsData
,
391 IN BOOLEAN RetrieveData
,
392 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
393 IN CONST CHAR16
*VariableName OPTIONAL
398 FORMSET_STORAGE
*Storage
;
399 FORM_BROWSER_FORMSET
*FormSet
;
406 if (ResultsDataSize
== NULL
|| ResultsData
== NULL
) {
407 return EFI_INVALID_PARAMETER
;
410 if (gCurrentSelection
== NULL
) {
411 return EFI_NOT_READY
;
416 FormSet
= gCurrentSelection
->FormSet
;
419 // Find target storage
421 Link
= GetFirstNode (&FormSet
->StorageListHead
);
422 if (IsNull (&FormSet
->StorageListHead
, Link
)) {
423 return EFI_UNSUPPORTED
;
426 if (VariableGuid
!= NULL
) {
428 // Try to find target storage
431 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
432 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
433 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
435 if (CompareGuid (&Storage
->Guid
, (EFI_GUID
*) VariableGuid
)) {
436 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
438 // Buffer storage require both GUID and Name
440 if (VariableName
== NULL
) {
441 return EFI_NOT_FOUND
;
444 if (StrCmp (Storage
->Name
, (CHAR16
*) VariableName
) != 0) {
454 return EFI_NOT_FOUND
;
458 // GUID/Name is not specified, take the first storage in FormSet
460 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
465 // Skip if there is no RequestElement
467 if (Storage
->ElementCount
== 0) {
472 // Generate <ConfigResp>
474 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
475 if (EFI_ERROR (Status
)) {
480 // Skip <ConfigHdr> and '&' to point to <ConfigBody>
482 StrPtr
= ConfigResp
+ StrLen (Storage
->ConfigHdr
) + 1;
484 BufferSize
= StrSize (StrPtr
);
485 if (*ResultsDataSize
< BufferSize
) {
486 *ResultsDataSize
= BufferSize
;
488 FreePool (ConfigResp
);
489 return EFI_BUFFER_TOO_SMALL
;
492 *ResultsDataSize
= BufferSize
;
493 CopyMem (ResultsData
, StrPtr
, BufferSize
);
495 FreePool (ConfigResp
);
498 // Prepare <ConfigResp>
500 TmpSize
= StrLen (ResultsData
);
501 BufferSize
= (TmpSize
+ StrLen (Storage
->ConfigHdr
) + 2) * sizeof (CHAR16
);
502 ConfigResp
= AllocateZeroPool (BufferSize
);
503 ASSERT (ConfigResp
!= NULL
);
505 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
506 StrCat (ConfigResp
, L
"&");
507 StrCat (ConfigResp
, ResultsData
);
510 // Update Browser uncommited data
512 Status
= ConfigRespToStorage (Storage
, ConfigResp
);
513 if (EFI_ERROR (Status
)) {
523 Initialize Setup Browser driver.
525 @param ImageHandle The image handle.
526 @param SystemTable The system table.
528 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
529 @return Other value if failed to initialize the Setup Browser module.
535 IN EFI_HANDLE ImageHandle
,
536 IN EFI_SYSTEM_TABLE
*SystemTable
542 // Locate required Hii relative protocols
544 Status
= gBS
->LocateProtocol (
545 &gEfiHiiDatabaseProtocolGuid
,
547 (VOID
**) &mHiiDatabase
549 ASSERT_EFI_ERROR (Status
);
551 Status
= gBS
->LocateProtocol (
552 &gEfiHiiStringProtocolGuid
,
554 (VOID
**) &mHiiString
556 ASSERT_EFI_ERROR (Status
);
558 Status
= gBS
->LocateProtocol (
559 &gEfiHiiConfigRoutingProtocolGuid
,
561 (VOID
**) &mHiiConfigRouting
563 ASSERT_EFI_ERROR (Status
);
566 // Publish our HII data
568 gHiiHandle
= HiiAddPackages (
574 ASSERT (gHiiHandle
!= NULL
);
577 // Initialize Driver private data
579 gBannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
580 ASSERT (gBannerData
!= NULL
);
583 // Install FormBrowser2 protocol
585 mPrivateData
.Handle
= NULL
;
586 Status
= gBS
->InstallProtocolInterface (
587 &mPrivateData
.Handle
,
588 &gEfiFormBrowser2ProtocolGuid
,
589 EFI_NATIVE_INTERFACE
,
590 &mPrivateData
.FormBrowser2
592 ASSERT_EFI_ERROR (Status
);
599 Create a new string in HII Package List.
601 @param String The String to be added
602 @param HiiHandle The package list in the HII database to insert the
605 @return The output string.
611 IN EFI_HII_HANDLE HiiHandle
614 EFI_STRING_ID StringId
;
616 StringId
= HiiSetString (HiiHandle
, 0, String
, NULL
);
617 ASSERT (StringId
!= 0);
624 Delete a string from HII Package List.
626 @param StringId Id of the string in HII database.
627 @param HiiHandle The HII package list handle.
629 @retval EFI_SUCCESS The string was deleted successfully.
634 IN EFI_STRING_ID StringId
,
635 IN EFI_HII_HANDLE HiiHandle
640 NullChar
= CHAR_NULL
;
641 HiiSetString (HiiHandle
, StringId
, &NullChar
, NULL
);
647 Get the string based on the StringId and HII Package List Handle.
649 @param Token The String's ID.
650 @param HiiHandle The package list in the HII database to search for
651 the specified string.
653 @return The output string.
658 IN EFI_STRING_ID Token
,
659 IN EFI_HII_HANDLE HiiHandle
664 String
= HiiGetString (HiiHandle
, Token
, NULL
);
665 if (String
== NULL
) {
666 String
= AllocateCopyPool (sizeof (mUnknownString
), mUnknownString
);
667 ASSERT (String
!= NULL
);
669 return (CHAR16
*) String
;
674 Allocate new memory and then copy the Unicode string Source to Destination.
676 @param Dest Location to copy string
677 @param Src String to copy
682 IN OUT CHAR16
**Dest
,
689 *Dest
= AllocateCopyPool (StrSize (Src
), Src
);
690 ASSERT (*Dest
!= NULL
);
695 Allocate new memory and concatinate Source on the end of Destination.
697 @param Dest String to added to the end of.
698 @param Src String to concatinate.
703 IN OUT CHAR16
**Dest
,
711 NewStringCpy (Dest
, Src
);
715 TmpSize
= StrSize (*Dest
);
716 NewString
= AllocateZeroPool (TmpSize
+ StrSize (Src
) - 1);
717 ASSERT (NewString
!= NULL
);
719 StrCpy (NewString
, *Dest
);
720 StrCat (NewString
, Src
);
728 Synchronize Storage's Edit copy to Shadow copy.
730 @param Storage The Storage to be synchronized.
735 IN FORMSET_STORAGE
*Storage
739 NAME_VALUE_NODE
*Node
;
741 switch (Storage
->Type
) {
742 case EFI_HII_VARSTORE_BUFFER
:
743 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
746 case EFI_HII_VARSTORE_NAME_VALUE
:
747 Link
= GetFirstNode (&Storage
->NameValueListHead
);
748 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
749 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
751 NewStringCpy (&Node
->Value
, Node
->EditValue
);
753 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
757 case EFI_HII_VARSTORE_EFI_VARIABLE
:
765 Get Value for given Name from a NameValue Storage.
767 @param Storage The NameValue Storage.
768 @param Name The Name.
769 @param Value The retured Value.
771 @retval EFI_SUCCESS Value found for given Name.
772 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
777 IN FORMSET_STORAGE
*Storage
,
779 IN OUT CHAR16
**Value
783 NAME_VALUE_NODE
*Node
;
787 Link
= GetFirstNode (&Storage
->NameValueListHead
);
788 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
789 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
791 if (StrCmp (Name
, Node
->Name
) == 0) {
792 NewStringCpy (Value
, Node
->EditValue
);
796 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
799 return EFI_NOT_FOUND
;
804 Set Value of given Name in a NameValue Storage.
806 @param Storage The NameValue Storage.
807 @param Name The Name.
808 @param Value The Value to set.
810 @retval EFI_SUCCESS Value found for given Name.
811 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
816 IN FORMSET_STORAGE
*Storage
,
822 NAME_VALUE_NODE
*Node
;
824 Link
= GetFirstNode (&Storage
->NameValueListHead
);
825 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
826 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
828 if (StrCmp (Name
, Node
->Name
) == 0) {
829 if (Node
->EditValue
!= NULL
) {
830 FreePool (Node
->EditValue
);
832 Node
->EditValue
= AllocateCopyPool (StrSize (Value
), Value
);
833 ASSERT (Node
->EditValue
!= NULL
);
837 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
840 return EFI_NOT_FOUND
;
845 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
847 @param Storage The Storage to be conveted.
848 @param ConfigResp The returned <ConfigResp>.
850 @retval EFI_SUCCESS Convert success.
851 @retval EFI_INVALID_PARAMETER Incorrect storage type.
855 StorageToConfigResp (
856 IN FORMSET_STORAGE
*Storage
,
857 IN CHAR16
**ConfigResp
863 NAME_VALUE_NODE
*Node
;
865 Status
= EFI_SUCCESS
;
867 switch (Storage
->Type
) {
868 case EFI_HII_VARSTORE_BUFFER
:
869 Status
= mHiiConfigRouting
->BlockToConfig (
871 Storage
->ConfigRequest
,
879 case EFI_HII_VARSTORE_NAME_VALUE
:
881 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
883 Link
= GetFirstNode (&Storage
->NameValueListHead
);
884 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
885 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
887 NewStringCat (ConfigResp
, L
"&");
888 NewStringCat (ConfigResp
, Node
->Name
);
889 NewStringCat (ConfigResp
, L
"=");
890 NewStringCat (ConfigResp
, Node
->EditValue
);
892 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
896 case EFI_HII_VARSTORE_EFI_VARIABLE
:
898 Status
= EFI_INVALID_PARAMETER
;
907 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
909 @param Storage The Storage to receive the settings.
910 @param ConfigResp The <ConfigResp> to be converted.
912 @retval EFI_SUCCESS Convert success.
913 @retval EFI_INVALID_PARAMETER Incorrect storage type.
917 ConfigRespToStorage (
918 IN FORMSET_STORAGE
*Storage
,
919 IN CHAR16
*ConfigResp
929 Status
= EFI_SUCCESS
;
931 switch (Storage
->Type
) {
932 case EFI_HII_VARSTORE_BUFFER
:
933 BufferSize
= Storage
->Size
;
934 Status
= mHiiConfigRouting
->ConfigToBlock (
943 case EFI_HII_VARSTORE_NAME_VALUE
:
944 StrPtr
= StrStr (ConfigResp
, L
"PATH");
945 if (StrPtr
== NULL
) {
948 StrPtr
= StrStr (ConfigResp
, L
"&");
949 while (StrPtr
!= NULL
) {
955 StrPtr
= StrStr (StrPtr
, L
"=");
956 if (StrPtr
== NULL
) {
966 StrPtr
= StrStr (StrPtr
, L
"&");
967 if (StrPtr
!= NULL
) {
970 SetValueByName (Storage
, Name
, Value
);
974 case EFI_HII_VARSTORE_EFI_VARIABLE
:
976 Status
= EFI_INVALID_PARAMETER
;
985 Get Question's current Value.
987 @param FormSet FormSet data structure.
988 @param Form Form data structure.
989 @param Question Question to be initialized.
990 @param Cached TRUE: get from Edit copy FALSE: get from original
993 @retval EFI_SUCCESS The function completed successfully.
998 IN FORM_BROWSER_FORMSET
*FormSet
,
999 IN FORM_BROWSER_FORM
*Form
,
1000 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1010 FORMSET_STORAGE
*Storage
;
1011 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1012 CHAR16
*ConfigRequest
;
1020 BOOLEAN IsBufferStorage
;
1025 Status
= EFI_SUCCESS
;
1028 // Statement don't have storage, skip them
1030 if (Question
->QuestionId
== 0) {
1035 // Question value is provided by an Expression, evaluate it
1037 if (Question
->ValueExpression
!= NULL
) {
1038 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1039 if (!EFI_ERROR (Status
)) {
1040 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1046 // Question value is provided by RTC
1048 Storage
= Question
->Storage
;
1049 QuestionValue
= &Question
->HiiValue
.Value
;
1050 if (Storage
== NULL
) {
1052 // It's a Question without storage, or RTC date/time
1054 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1056 // Date and time define the same Flags bit
1058 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1059 case QF_DATE_STORAGE_TIME
:
1060 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1063 case QF_DATE_STORAGE_WAKEUP
:
1064 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1067 case QF_DATE_STORAGE_NORMAL
:
1070 // For date/time without storage
1075 if (EFI_ERROR (Status
)) {
1079 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1080 QuestionValue
->date
.Year
= EfiTime
.Year
;
1081 QuestionValue
->date
.Month
= EfiTime
.Month
;
1082 QuestionValue
->date
.Day
= EfiTime
.Day
;
1084 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1085 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1086 QuestionValue
->time
.Second
= EfiTime
.Second
;
1094 // Question value is provided by EFI variable
1096 StorageWidth
= Question
->StorageWidth
;
1097 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1098 if (Question
->BufferValue
!= NULL
) {
1099 Dst
= Question
->BufferValue
;
1101 Dst
= (UINT8
*) QuestionValue
;
1104 Status
= gRT
->GetVariable (
1105 Question
->VariableName
,
1112 // Always return success, even this EFI variable doesn't exist
1118 // Question Value is provided by Buffer Storage or NameValue Storage
1120 if (Question
->BufferValue
!= NULL
) {
1122 // This Question is password or orderedlist
1124 Dst
= Question
->BufferValue
;
1127 // Other type of Questions
1129 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1132 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1133 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1135 if (IsBufferStorage
) {
1137 // Copy from storage Edit buffer
1139 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1141 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1142 if (EFI_ERROR (Status
)) {
1146 LengthStr
= StrLen (Value
);
1147 Status
= EFI_SUCCESS
;
1150 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1151 // Add string tail char L'\0' into Length
1153 Length
= StorageWidth
+ sizeof (CHAR16
);
1154 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1155 Status
= EFI_BUFFER_TOO_SMALL
;
1157 StringPtr
= (CHAR16
*) Dst
;
1158 ZeroMem (TemStr
, sizeof (TemStr
));
1159 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1160 StrnCpy (TemStr
, Value
+ Index
, 4);
1161 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1164 // Add tailing L'\0' character
1166 StringPtr
[Index
/4] = L
'\0';
1169 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1170 Status
= EFI_BUFFER_TOO_SMALL
;
1172 ZeroMem (TemStr
, sizeof (TemStr
));
1173 for (Index
= 0; Index
< LengthStr
; Index
++) {
1174 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1175 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1176 if ((Index
& 1) == 0) {
1177 Dst
[Index
/2] = DigitUint8
;
1179 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1189 // Request current settings from Configuration Driver
1191 if (FormSet
->ConfigAccess
== NULL
) {
1192 return EFI_NOT_FOUND
;
1196 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1197 // <ConfigHdr> + "&" + <VariableName>
1199 if (IsBufferStorage
) {
1200 Length
= StrLen (Storage
->ConfigHdr
);
1201 Length
+= StrLen (Question
->BlockName
);
1203 Length
= StrLen (Storage
->ConfigHdr
);
1204 Length
+= StrLen (Question
->VariableName
) + 1;
1206 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1207 ASSERT (ConfigRequest
!= NULL
);
1209 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1210 if (IsBufferStorage
) {
1211 StrCat (ConfigRequest
, Question
->BlockName
);
1213 StrCat (ConfigRequest
, L
"&");
1214 StrCat (ConfigRequest
, Question
->VariableName
);
1217 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1218 FormSet
->ConfigAccess
,
1223 if (EFI_ERROR (Status
)) {
1228 // Skip <ConfigRequest>
1230 Value
= Result
+ Length
;
1231 if (IsBufferStorage
) {
1237 if (*Value
!= '=') {
1239 return EFI_NOT_FOUND
;
1242 // Skip '=', point to value
1247 // Suppress <AltResp> if any
1250 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1255 LengthStr
= StrLen (Value
);
1256 Status
= EFI_SUCCESS
;
1257 if (!IsBufferStorage
&& IsString
) {
1259 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1260 // Add string tail char L'\0' into Length
1262 Length
= StorageWidth
+ sizeof (CHAR16
);
1263 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1264 Status
= EFI_BUFFER_TOO_SMALL
;
1266 StringPtr
= (CHAR16
*) Dst
;
1267 ZeroMem (TemStr
, sizeof (TemStr
));
1268 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1269 StrnCpy (TemStr
, Value
+ Index
, 4);
1270 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1273 // Add tailing L'\0' character
1275 StringPtr
[Index
/4] = L
'\0';
1278 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1279 Status
= EFI_BUFFER_TOO_SMALL
;
1281 ZeroMem (TemStr
, sizeof (TemStr
));
1282 for (Index
= 0; Index
< LengthStr
; Index
++) {
1283 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1284 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1285 if ((Index
& 1) == 0) {
1286 Dst
[Index
/2] = DigitUint8
;
1288 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1294 if (EFI_ERROR (Status
)) {
1300 // Synchronize Edit Buffer
1302 if (IsBufferStorage
) {
1303 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1305 SetValueByName (Storage
, Question
->VariableName
, Value
);
1316 Save Question Value to edit copy(cached) or Storage(uncached).
1318 @param FormSet FormSet data structure.
1319 @param Form Form data structure.
1320 @param Question Pointer to the Question.
1321 @param Cached TRUE: set to Edit copy FALSE: set to original
1324 @retval EFI_SUCCESS The function completed successfully.
1329 IN FORM_BROWSER_FORMSET
*FormSet
,
1330 IN FORM_BROWSER_FORM
*Form
,
1331 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1342 FORMSET_STORAGE
*Storage
;
1343 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1348 BOOLEAN IsBufferStorage
;
1355 Status
= EFI_SUCCESS
;
1358 // Statement don't have storage, skip them
1360 if (Question
->QuestionId
== 0) {
1365 // If Question value is provided by an Expression, then it is read only
1367 if (Question
->ValueExpression
!= NULL
) {
1372 // Question value is provided by RTC
1374 Storage
= Question
->Storage
;
1375 QuestionValue
= &Question
->HiiValue
.Value
;
1376 if (Storage
== NULL
) {
1378 // It's a Question without storage, or RTC date/time
1380 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1382 // Date and time define the same Flags bit
1384 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1385 case QF_DATE_STORAGE_TIME
:
1386 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1389 case QF_DATE_STORAGE_WAKEUP
:
1390 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1393 case QF_DATE_STORAGE_NORMAL
:
1396 // For date/time without storage
1401 if (EFI_ERROR (Status
)) {
1405 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1406 EfiTime
.Year
= QuestionValue
->date
.Year
;
1407 EfiTime
.Month
= QuestionValue
->date
.Month
;
1408 EfiTime
.Day
= QuestionValue
->date
.Day
;
1410 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1411 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1412 EfiTime
.Second
= QuestionValue
->time
.Second
;
1415 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1416 Status
= gRT
->SetTime (&EfiTime
);
1418 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1426 // Question value is provided by EFI variable
1428 StorageWidth
= Question
->StorageWidth
;
1429 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1430 if (Question
->BufferValue
!= NULL
) {
1431 Src
= Question
->BufferValue
;
1433 Src
= (UINT8
*) QuestionValue
;
1436 Status
= gRT
->SetVariable (
1437 Question
->VariableName
,
1439 Storage
->Attributes
,
1447 // Question Value is provided by Buffer Storage or NameValue Storage
1449 if (Question
->BufferValue
!= NULL
) {
1450 Src
= Question
->BufferValue
;
1452 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1455 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1456 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1457 if (IsBufferStorage
) {
1459 // Copy to storage edit buffer
1461 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1465 // Allocate enough string buffer.
1468 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1469 Value
= AllocateZeroPool (BufferLen
);
1470 ASSERT (Value
!= NULL
);
1472 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1474 TemName
= (CHAR16
*) Src
;
1476 for (; *TemName
!= L
'\0'; TemName
++) {
1477 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1480 BufferLen
= StorageWidth
* 2 + 1;
1481 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1482 ASSERT (Value
!= NULL
);
1484 // Convert Buffer to Hex String
1486 TemBuffer
= Src
+ StorageWidth
- 1;
1488 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1489 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1493 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
);
1499 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1500 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1502 if (IsBufferStorage
) {
1503 Length
= StrLen (Question
->BlockName
) + 7;
1505 Length
= StrLen (Question
->VariableName
) + 2;
1507 if (!IsBufferStorage
&& IsString
) {
1508 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1510 Length
+= (StorageWidth
* 2);
1512 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1513 ASSERT (ConfigResp
!= NULL
);
1515 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1516 if (IsBufferStorage
) {
1517 StrCat (ConfigResp
, Question
->BlockName
);
1518 StrCat (ConfigResp
, L
"&VALUE=");
1520 StrCat (ConfigResp
, L
"&");
1521 StrCat (ConfigResp
, Question
->VariableName
);
1522 StrCat (ConfigResp
, L
"=");
1525 Value
= ConfigResp
+ StrLen (ConfigResp
);
1527 if (!IsBufferStorage
&& IsString
) {
1529 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1531 TemName
= (CHAR16
*) Src
;
1533 for (; *TemName
!= L
'\0'; TemName
++) {
1534 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1538 // Convert Buffer to Hex String
1540 TemBuffer
= Src
+ StorageWidth
- 1;
1542 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1543 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1548 // Convert to lower char.
1550 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1551 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1552 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1557 // Submit Question Value to Configuration Driver
1559 if (FormSet
->ConfigAccess
!= NULL
) {
1560 Status
= FormSet
->ConfigAccess
->RouteConfig (
1561 FormSet
->ConfigAccess
,
1565 if (EFI_ERROR (Status
)) {
1566 FreePool (ConfigResp
);
1570 FreePool (ConfigResp
);
1573 // Synchronize shadow Buffer
1575 SynchronizeStorage (Storage
);
1583 Perform inconsistent check for a Form.
1585 @param FormSet FormSet data structure.
1586 @param Form Form data structure.
1587 @param Question The Question to be validated.
1588 @param Type Validation type: InConsistent or NoSubmit
1590 @retval EFI_SUCCESS Form validation pass.
1591 @retval other Form validation failed.
1596 IN FORM_BROWSER_FORMSET
*FormSet
,
1597 IN FORM_BROWSER_FORM
*Form
,
1598 IN FORM_BROWSER_STATEMENT
*Question
,
1604 LIST_ENTRY
*ListHead
;
1607 FORM_EXPRESSION
*Expression
;
1609 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1610 ListHead
= &Question
->InconsistentListHead
;
1611 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1612 ListHead
= &Question
->NoSubmitListHead
;
1614 return EFI_UNSUPPORTED
;
1617 Link
= GetFirstNode (ListHead
);
1618 while (!IsNull (ListHead
, Link
)) {
1619 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1622 // Evaluate the expression
1624 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1625 if (EFI_ERROR (Status
)) {
1629 if (Expression
->Result
.Value
.b
) {
1631 // Condition meet, show up error message
1633 if (Expression
->Error
!= 0) {
1634 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1636 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1637 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1641 return EFI_NOT_READY
;
1644 Link
= GetNextNode (ListHead
, Link
);
1652 Perform NoSubmit check for a Form.
1654 @param FormSet FormSet data structure.
1655 @param Form Form data structure.
1657 @retval EFI_SUCCESS Form validation pass.
1658 @retval other Form validation failed.
1663 IN FORM_BROWSER_FORMSET
*FormSet
,
1664 IN FORM_BROWSER_FORM
*Form
1669 FORM_BROWSER_STATEMENT
*Question
;
1671 Link
= GetFirstNode (&Form
->StatementListHead
);
1672 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1673 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1675 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1676 if (EFI_ERROR (Status
)) {
1680 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1690 @param FormSet FormSet data structure.
1691 @param Form Form data structure.
1693 @retval EFI_SUCCESS The function completed successfully.
1698 IN FORM_BROWSER_FORMSET
*FormSet
,
1699 IN FORM_BROWSER_FORM
*Form
1704 EFI_STRING ConfigResp
;
1705 EFI_STRING Progress
;
1706 FORMSET_STORAGE
*Storage
;
1709 // Validate the Form by NoSubmit check
1711 Status
= NoSubmitCheck (FormSet
, Form
);
1712 if (EFI_ERROR (Status
)) {
1717 // Submit Buffer storage or Name/Value storage
1719 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1720 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1721 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1722 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1724 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1729 // Skip if there is no RequestElement
1731 if (Storage
->ElementCount
== 0) {
1736 // Prepare <ConfigResp>
1738 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
1739 if (EFI_ERROR (Status
)) {
1744 // Send <ConfigResp> to Configuration Driver
1746 if (FormSet
->ConfigAccess
!= NULL
) {
1747 Status
= FormSet
->ConfigAccess
->RouteConfig (
1748 FormSet
->ConfigAccess
,
1752 if (EFI_ERROR (Status
)) {
1753 FreePool (ConfigResp
);
1757 FreePool (ConfigResp
);
1760 // Config success, update storage shadow Buffer
1762 SynchronizeStorage (Storage
);
1765 gNvUpdateRequired
= FALSE
;
1772 Reset Question to its default value.
1774 @param FormSet The form set.
1775 @param Form The form.
1776 @param Question The question.
1777 @param DefaultId The Class of the default.
1779 @retval EFI_SUCCESS Question is reset to default value.
1783 GetQuestionDefault (
1784 IN FORM_BROWSER_FORMSET
*FormSet
,
1785 IN FORM_BROWSER_FORM
*Form
,
1786 IN FORM_BROWSER_STATEMENT
*Question
,
1792 QUESTION_DEFAULT
*Default
;
1793 QUESTION_OPTION
*Option
;
1794 EFI_HII_VALUE
*HiiValue
;
1796 EFI_STRING StrValue
;
1798 Status
= EFI_SUCCESS
;
1802 // Statement don't have storage, skip them
1804 if (Question
->QuestionId
== 0) {
1809 // There are three ways to specify default value for a Question:
1810 // 1, use nested EFI_IFR_DEFAULT (highest priority)
1811 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
1812 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
1814 HiiValue
= &Question
->HiiValue
;
1817 // EFI_IFR_DEFAULT has highest priority
1819 if (!IsListEmpty (&Question
->DefaultListHead
)) {
1820 Link
= GetFirstNode (&Question
->DefaultListHead
);
1821 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
1822 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1824 if (Default
->DefaultId
== DefaultId
) {
1825 if (Default
->ValueExpression
!= NULL
) {
1827 // Default is provided by an Expression, evaluate it
1829 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
1830 if (EFI_ERROR (Status
)) {
1834 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1837 // Default value is embedded in EFI_IFR_DEFAULT
1839 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
1842 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1843 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
1844 if (StrValue
== NULL
) {
1845 return EFI_NOT_FOUND
;
1847 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
1853 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
1858 // EFI_ONE_OF_OPTION
1860 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
1861 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1863 // OneOfOption could only provide Standard and Manufacturing default
1865 Link
= GetFirstNode (&Question
->OptionListHead
);
1866 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1867 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1869 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
1870 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
1872 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1877 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1883 // EFI_IFR_CHECKBOX - lowest priority
1885 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
1886 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1888 // Checkbox could only provide Standard and Manufacturing default
1890 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
1891 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
1893 HiiValue
->Value
.b
= TRUE
;
1895 HiiValue
->Value
.b
= FALSE
;
1903 // For Questions without default
1905 switch (Question
->Operand
) {
1906 case EFI_IFR_ONE_OF_OP
:
1908 // Take first oneof option as oneof's default value
1910 if (ValueToOption (Question
, HiiValue
) == NULL
) {
1911 Link
= GetFirstNode (&Question
->OptionListHead
);
1912 if (!IsNull (&Question
->OptionListHead
, Link
)) {
1913 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1914 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1919 case EFI_IFR_ORDERED_LIST_OP
:
1921 // Take option sequence in IFR as ordered list's default value
1924 Link
= GetFirstNode (&Question
->OptionListHead
);
1925 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1926 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1928 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
1931 if (Index
>= Question
->MaxContainers
) {
1935 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1940 Status
= EFI_NOT_FOUND
;
1949 Reset Questions in a Form to their default value.
1951 @param FormSet FormSet data structure.
1952 @param Form The Form which to be reset.
1953 @param DefaultId The Class of the default.
1955 @retval EFI_SUCCESS The function completed successfully.
1959 ExtractFormDefault (
1960 IN FORM_BROWSER_FORMSET
*FormSet
,
1961 IN FORM_BROWSER_FORM
*Form
,
1967 FORM_BROWSER_STATEMENT
*Question
;
1969 Link
= GetFirstNode (&Form
->StatementListHead
);
1970 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1971 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1972 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1975 // If Question is disabled, don't reset it to default
1977 if (Question
->DisableExpression
!= NULL
) {
1978 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
1979 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
1985 // Reset Question to its default value
1987 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
1988 if (EFI_ERROR (Status
)) {
1993 // Synchronize Buffer storage's Edit buffer
1995 if ((Question
->Storage
!= NULL
) &&
1996 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1997 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2005 Initialize Question's Edit copy from Storage.
2007 @param Selection Selection contains the information about
2008 the Selection, form and formset to be displayed.
2009 Selection action may be updated in retrieve callback.
2010 @param FormSet FormSet data structure.
2011 @param Form Form data structure.
2013 @retval EFI_SUCCESS The function completed successfully.
2018 IN OUT UI_MENU_SELECTION
*Selection
,
2019 IN FORM_BROWSER_FORMSET
*FormSet
,
2020 IN FORM_BROWSER_FORM
*Form
2025 FORM_BROWSER_STATEMENT
*Question
;
2028 EFI_HII_VALUE
*HiiValue
;
2029 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2031 Link
= GetFirstNode (&Form
->StatementListHead
);
2032 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2033 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2036 // Initialize local copy of Value for each Question
2038 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2039 if (EFI_ERROR (Status
)) {
2044 // Check whether EfiVarstore with CallBack can be got.
2046 if ((Question
->QuestionId
!= 0) && (Question
->Storage
!= NULL
) &&
2047 (Question
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) &&
2048 ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
2050 // ConfigAccess can't be NULL.
2052 if (FormSet
->ConfigAccess
== NULL
) {
2053 return EFI_UNSUPPORTED
;
2056 // Check QuestionValue does exist.
2058 StorageWidth
= Question
->StorageWidth
;
2059 if (Question
->BufferValue
!= NULL
) {
2060 BufferValue
= Question
->BufferValue
;
2062 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2064 Status
= gRT
->GetVariable (
2065 Question
->VariableName
,
2066 &Question
->Storage
->Guid
,
2072 if (!EFI_ERROR (Status
)) {
2073 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2074 HiiValue
= &Question
->HiiValue
;
2075 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2076 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2078 // Create String in HII database for Configuration Driver to retrieve
2080 HiiValue
->Value
.string
= NewString ((CHAR16
*) Question
->BufferValue
, FormSet
->HiiHandle
);
2081 } else if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2082 BufferValue
= Question
->BufferValue
;
2085 Status
= FormSet
->ConfigAccess
->Callback (
2086 FormSet
->ConfigAccess
,
2087 EFI_BROWSER_ACTION_RETRIEVE
,
2088 Question
->QuestionId
,
2090 (EFI_IFR_TYPE_VALUE
*) BufferValue
,
2094 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2096 // Clean the String in HII Database
2098 DeleteString (HiiValue
->Value
.string
, FormSet
->HiiHandle
);
2101 if (!EFI_ERROR (Status
)) {
2102 switch (ActionRequest
) {
2103 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2104 gResetRequired
= TRUE
;
2107 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2109 // Till now there is no uncommitted data, so ignore this request
2113 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2114 Selection
->Action
= UI_ACTION_EXIT
;
2124 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2131 Initialize Question's Edit copy from Storage for the whole Formset.
2133 @param Selection Selection contains the information about
2134 the Selection, form and formset to be displayed.
2135 Selection action may be updated in retrieve callback.
2136 @param FormSet FormSet data structure.
2138 @retval EFI_SUCCESS The function completed successfully.
2143 IN OUT UI_MENU_SELECTION
*Selection
,
2144 IN FORM_BROWSER_FORMSET
*FormSet
2149 FORM_BROWSER_FORM
*Form
;
2151 Link
= GetFirstNode (&FormSet
->FormListHead
);
2152 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2153 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2156 // Initialize local copy of Value for each Form
2158 Status
= LoadFormConfig (Selection
, FormSet
, Form
);
2159 if (EFI_ERROR (Status
)) {
2163 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2170 Fill storage's edit copy with settings requested from Configuration Driver.
2172 @param FormSet FormSet data structure.
2173 @param Storage Buffer Storage.
2175 @retval EFI_SUCCESS The function completed successfully.
2180 IN FORM_BROWSER_FORMSET
*FormSet
,
2181 IN FORMSET_STORAGE
*Storage
2185 EFI_STRING Progress
;
2189 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2193 if (FormSet
->ConfigAccess
== NULL
) {
2194 return EFI_NOT_FOUND
;
2197 if (Storage
->ElementCount
== 0) {
2199 // Skip if there is no RequestElement
2205 // Request current settings from Configuration Driver
2207 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2208 FormSet
->ConfigAccess
,
2209 Storage
->ConfigRequest
,
2213 if (EFI_ERROR (Status
)) {
2218 // Convert Result from <ConfigAltResp> to <ConfigResp>
2220 StrPtr
= StrStr (Result
, L
"ALTCFG");
2221 if (StrPtr
!= NULL
) {
2225 Status
= ConfigRespToStorage (Storage
, Result
);
2232 Copy uncommitted data from source Storage to destination Storage.
2234 @param Dst Target Storage for uncommitted data.
2235 @param Src Source Storage for uncommitted data.
2237 @retval EFI_SUCCESS The function completed successfully.
2238 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2243 IN OUT FORMSET_STORAGE
*Dst
,
2244 IN FORMSET_STORAGE
*Src
2248 NAME_VALUE_NODE
*Node
;
2250 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2251 return EFI_INVALID_PARAMETER
;
2254 switch (Src
->Type
) {
2255 case EFI_HII_VARSTORE_BUFFER
:
2256 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
2259 case EFI_HII_VARSTORE_NAME_VALUE
:
2260 Link
= GetFirstNode (&Src
->NameValueListHead
);
2261 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
2262 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2264 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
);
2266 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
2270 case EFI_HII_VARSTORE_EFI_VARIABLE
:
2280 Get current setting of Questions.
2282 @param FormSet FormSet data structure.
2284 @retval EFI_SUCCESS The function completed successfully.
2288 InitializeCurrentSetting (
2289 IN OUT FORM_BROWSER_FORMSET
*FormSet
2294 FORMSET_STORAGE
*Storage
;
2295 FORMSET_STORAGE
*StorageSrc
;
2296 FORMSET_STORAGE
*OldStorage
;
2297 FORM_BROWSER_FORM
*Form
;
2301 // Extract default from IFR binary
2303 Link
= GetFirstNode (&FormSet
->FormListHead
);
2304 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2305 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2307 Status
= ExtractFormDefault (FormSet
, Form
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2309 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2313 // Request current settings from Configuration Driver
2315 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2316 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2317 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2320 if (gOldFormSet
!= NULL
) {
2322 // Try to find the Storage in backup formset gOldFormSet
2324 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
2325 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
2326 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
2328 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
2329 OldStorage
= StorageSrc
;
2333 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
2337 if (OldStorage
== NULL
) {
2339 // Storage is not found in backup formset, request it from ConfigDriver
2341 Status
= LoadStorage (FormSet
, Storage
);
2344 // Storage found in backup formset, use it
2346 Status
= CopyStorage (Storage
, OldStorage
);
2350 // Now Edit Buffer is filled with default values(lower priority) and current
2351 // settings(higher priority), sychronize it to shadow Buffer
2353 if (!EFI_ERROR (Status
)) {
2354 SynchronizeStorage (Storage
);
2357 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2365 Fetch the Ifr binary data of a FormSet.
2367 @param Handle PackageList Handle
2368 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2369 specified (NULL or zero GUID), take the first
2370 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2371 found in package list.
2372 On output, GUID of the formset found(if not NULL).
2373 @param BinaryLength The length of the FormSet IFR binary.
2374 @param BinaryData The buffer designed to receive the FormSet.
2376 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
2377 BufferLength was updated.
2378 @retval EFI_INVALID_PARAMETER The handle is unknown.
2379 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
2380 be found with the requested FormId.
2385 IN EFI_HII_HANDLE Handle
,
2386 IN OUT EFI_GUID
*FormSetGuid
,
2387 OUT UINTN
*BinaryLength
,
2388 OUT UINT8
**BinaryData
2392 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2398 UINT32 PackageListLength
;
2399 EFI_HII_PACKAGE_HEADER PackageHeader
;
2401 UINT8 NumberOfClassGuid
;
2402 BOOLEAN ClassGuidMatch
;
2403 EFI_GUID
*ClassGuid
;
2404 EFI_GUID
*ComparingGuid
;
2408 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2411 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
2413 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
2414 ComparingGuid
= &gEfiHiiPlatformSetupFormsetGuid
;
2416 ComparingGuid
= FormSetGuid
;
2420 // Get HII PackageList
2423 HiiPackageList
= NULL
;
2424 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2425 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2426 HiiPackageList
= AllocatePool (BufferSize
);
2427 ASSERT (HiiPackageList
!= NULL
);
2429 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2431 if (EFI_ERROR (Status
)) {
2434 ASSERT (HiiPackageList
!= NULL
);
2437 // Get Form package from this HII package List
2439 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2441 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
2443 ClassGuidMatch
= FALSE
;
2444 while (Offset
< PackageListLength
) {
2445 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
2446 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2448 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
2450 // Search FormSet in this Form Package
2452 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
2453 while (Offset2
< PackageHeader
.Length
) {
2454 OpCodeData
= Package
+ Offset2
;
2456 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
2458 // Try to compare against formset GUID
2460 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2465 // Try to compare against formset class GUID
2467 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2468 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
2469 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
2470 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
2471 ClassGuidMatch
= TRUE
;
2475 if (ClassGuidMatch
) {
2480 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
2483 if (Offset2
< PackageHeader
.Length
) {
2485 // Target formset found
2491 Offset
+= PackageHeader
.Length
;
2494 if (Offset
>= PackageListLength
) {
2496 // Form package not found in this Package List
2498 FreePool (HiiPackageList
);
2499 return EFI_NOT_FOUND
;
2502 if (ClassGuidMatch
&& (FormSetGuid
!= NULL
)) {
2504 // Return the FormSet GUID
2506 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2510 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
2511 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
2512 // of the Form Package.
2514 *BinaryLength
= PackageHeader
.Length
- Offset2
;
2515 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
2517 FreePool (HiiPackageList
);
2519 if (*BinaryData
== NULL
) {
2520 return EFI_OUT_OF_RESOURCES
;
2528 Initialize the internal data structure of a FormSet.
2530 @param Handle PackageList Handle
2531 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2532 specified (NULL or zero GUID), take the first
2533 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2534 found in package list.
2535 On output, GUID of the formset found(if not NULL).
2536 @param FormSet FormSet data structure.
2538 @retval EFI_SUCCESS The function completed successfully.
2539 @retval EFI_NOT_FOUND The specified FormSet could not be found.
2544 IN EFI_HII_HANDLE Handle
,
2545 IN OUT EFI_GUID
*FormSetGuid
,
2546 OUT FORM_BROWSER_FORMSET
*FormSet
2550 EFI_HANDLE DriverHandle
;
2553 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
2554 if (EFI_ERROR (Status
)) {
2558 FormSet
->HiiHandle
= Handle
;
2559 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
2562 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
2564 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
2565 if (EFI_ERROR (Status
)) {
2568 FormSet
->DriverHandle
= DriverHandle
;
2569 Status
= gBS
->HandleProtocol (
2571 &gEfiHiiConfigAccessProtocolGuid
,
2572 (VOID
**) &FormSet
->ConfigAccess
2574 if (EFI_ERROR (Status
)) {
2576 // Configuration Driver don't attach ConfigAccess protocol to its HII package
2577 // list, then there will be no configuration action required
2579 FormSet
->ConfigAccess
= NULL
;
2583 // Parse the IFR binary OpCodes
2585 Status
= ParseOpCodes (FormSet
);
2586 if (EFI_ERROR (Status
)) {
2591 // Set VFR type by FormSet SubClass field
2593 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
2594 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2595 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
2599 // Set VFR type by FormSet class guid
2601 for (Index
= 0; Index
< 3; Index
++) {
2602 if (CompareGuid (&FormSet
->ClassGuid
[Index
], &gEfiHiiPlatformSetupFormsetGuid
)) {
2603 gClassOfVfr
|= FORMSET_CLASS_PLATFORM_SETUP
;
2608 if ((gClassOfVfr
& FORMSET_CLASS_FRONT_PAGE
) == FORMSET_CLASS_FRONT_PAGE
) {
2609 gFrontPageHandle
= FormSet
->HiiHandle
;
2613 // Match GUID to find out the function key setting. If match fail, use the default setting.
2615 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
2616 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
2618 // Update the function key setting.
2620 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
2622 // Function key prompt can not be displayed if the function key has been disabled.
2624 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2625 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2628 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2629 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2639 Save globals used by previous call to SendForm(). SendForm() may be called from
2640 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
2641 So, save globals of previous call to SendForm() and restore them upon exit.
2645 SaveBrowserContext (
2649 BROWSER_CONTEXT
*Context
;
2651 gBrowserContextCount
++;
2652 if (gBrowserContextCount
== 1) {
2654 // This is not reentry of SendForm(), no context to save
2659 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
2660 ASSERT (Context
!= NULL
);
2662 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
2665 // Save FormBrowser context
2667 Context
->BannerData
= gBannerData
;
2668 Context
->ClassOfVfr
= gClassOfVfr
;
2669 Context
->FunctionKeySetting
= gFunctionKeySetting
;
2670 Context
->ResetRequired
= gResetRequired
;
2671 Context
->NvUpdateRequired
= gNvUpdateRequired
;
2672 Context
->Direction
= gDirection
;
2673 Context
->FunctionNineString
= gFunctionNineString
;
2674 Context
->FunctionTenString
= gFunctionTenString
;
2675 Context
->EnterString
= gEnterString
;
2676 Context
->EnterCommitString
= gEnterCommitString
;
2677 Context
->EnterEscapeString
= gEnterEscapeString
;
2678 Context
->EscapeString
= gEscapeString
;
2679 Context
->SaveFailed
= gSaveFailed
;
2680 Context
->MoveHighlight
= gMoveHighlight
;
2681 Context
->MakeSelection
= gMakeSelection
;
2682 Context
->DecNumericInput
= gDecNumericInput
;
2683 Context
->HexNumericInput
= gHexNumericInput
;
2684 Context
->ToggleCheckBox
= gToggleCheckBox
;
2685 Context
->PromptForData
= gPromptForData
;
2686 Context
->PromptForPassword
= gPromptForPassword
;
2687 Context
->PromptForNewPassword
= gPromptForNewPassword
;
2688 Context
->ConfirmPassword
= gConfirmPassword
;
2689 Context
->ConfirmError
= gConfirmError
;
2690 Context
->PassowordInvalid
= gPassowordInvalid
;
2691 Context
->PressEnter
= gPressEnter
;
2692 Context
->EmptyString
= gEmptyString
;
2693 Context
->AreYouSure
= gAreYouSure
;
2694 Context
->YesResponse
= gYesResponse
;
2695 Context
->NoResponse
= gNoResponse
;
2696 Context
->MiniString
= gMiniString
;
2697 Context
->PlusString
= gPlusString
;
2698 Context
->MinusString
= gMinusString
;
2699 Context
->AdjustNumber
= gAdjustNumber
;
2700 Context
->SaveChanges
= gSaveChanges
;
2701 Context
->OptionMismatch
= gOptionMismatch
;
2702 Context
->FormSuppress
= gFormSuppress
;
2703 Context
->PromptBlockWidth
= gPromptBlockWidth
;
2704 Context
->OptionBlockWidth
= gOptionBlockWidth
;
2705 Context
->HelpBlockWidth
= gHelpBlockWidth
;
2706 Context
->OldFormSet
= gOldFormSet
;
2707 Context
->MenuRefreshHead
= gMenuRefreshHead
;
2709 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
2710 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
2713 // Insert to FormBrowser context list
2715 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
2720 Restore globals used by previous call to SendForm().
2724 RestoreBrowserContext (
2729 BROWSER_CONTEXT
*Context
;
2731 ASSERT (gBrowserContextCount
!= 0);
2732 gBrowserContextCount
--;
2733 if (gBrowserContextCount
== 0) {
2735 // This is not reentry of SendForm(), no context to restore
2740 ASSERT (!IsListEmpty (&gBrowserContextList
));
2742 Link
= GetFirstNode (&gBrowserContextList
);
2743 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
2746 // Restore FormBrowser context
2748 gBannerData
= Context
->BannerData
;
2749 gClassOfVfr
= Context
->ClassOfVfr
;
2750 gFunctionKeySetting
= Context
->FunctionKeySetting
;
2751 gResetRequired
= Context
->ResetRequired
;
2752 gNvUpdateRequired
= Context
->NvUpdateRequired
;
2753 gDirection
= Context
->Direction
;
2754 gFunctionNineString
= Context
->FunctionNineString
;
2755 gFunctionTenString
= Context
->FunctionTenString
;
2756 gEnterString
= Context
->EnterString
;
2757 gEnterCommitString
= Context
->EnterCommitString
;
2758 gEnterEscapeString
= Context
->EnterEscapeString
;
2759 gEscapeString
= Context
->EscapeString
;
2760 gSaveFailed
= Context
->SaveFailed
;
2761 gMoveHighlight
= Context
->MoveHighlight
;
2762 gMakeSelection
= Context
->MakeSelection
;
2763 gDecNumericInput
= Context
->DecNumericInput
;
2764 gHexNumericInput
= Context
->HexNumericInput
;
2765 gToggleCheckBox
= Context
->ToggleCheckBox
;
2766 gPromptForData
= Context
->PromptForData
;
2767 gPromptForPassword
= Context
->PromptForPassword
;
2768 gPromptForNewPassword
= Context
->PromptForNewPassword
;
2769 gConfirmPassword
= Context
->ConfirmPassword
;
2770 gConfirmError
= Context
->ConfirmError
;
2771 gPassowordInvalid
= Context
->PassowordInvalid
;
2772 gPressEnter
= Context
->PressEnter
;
2773 gEmptyString
= Context
->EmptyString
;
2774 gAreYouSure
= Context
->AreYouSure
;
2775 gYesResponse
= Context
->YesResponse
;
2776 gNoResponse
= Context
->NoResponse
;
2777 gMiniString
= Context
->MiniString
;
2778 gPlusString
= Context
->PlusString
;
2779 gMinusString
= Context
->MinusString
;
2780 gAdjustNumber
= Context
->AdjustNumber
;
2781 gSaveChanges
= Context
->SaveChanges
;
2782 gOptionMismatch
= Context
->OptionMismatch
;
2783 gFormSuppress
= Context
->FormSuppress
;
2784 gPromptBlockWidth
= Context
->PromptBlockWidth
;
2785 gOptionBlockWidth
= Context
->OptionBlockWidth
;
2786 gHelpBlockWidth
= Context
->HelpBlockWidth
;
2787 gOldFormSet
= Context
->OldFormSet
;
2788 gMenuRefreshHead
= Context
->MenuRefreshHead
;
2790 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
2791 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
2794 // Remove from FormBrowser context list
2796 RemoveEntryList (&Context
->Link
);
2797 gBS
->FreePool (Context
);