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
);
1142 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1143 if (EFI_ERROR (Status
)) {
1147 ASSERT (Value
!= NULL
);
1148 LengthStr
= StrLen (Value
);
1149 Status
= EFI_SUCCESS
;
1152 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1153 // Add string tail char L'\0' into Length
1155 Length
= StorageWidth
+ sizeof (CHAR16
);
1156 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1157 Status
= EFI_BUFFER_TOO_SMALL
;
1159 StringPtr
= (CHAR16
*) Dst
;
1160 ZeroMem (TemStr
, sizeof (TemStr
));
1161 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1162 StrnCpy (TemStr
, Value
+ Index
, 4);
1163 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1166 // Add tailing L'\0' character
1168 StringPtr
[Index
/4] = L
'\0';
1171 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1172 Status
= EFI_BUFFER_TOO_SMALL
;
1174 ZeroMem (TemStr
, sizeof (TemStr
));
1175 for (Index
= 0; Index
< LengthStr
; Index
++) {
1176 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1177 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1178 if ((Index
& 1) == 0) {
1179 Dst
[Index
/2] = DigitUint8
;
1181 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1191 // Request current settings from Configuration Driver
1193 if (FormSet
->ConfigAccess
== NULL
) {
1194 return EFI_NOT_FOUND
;
1198 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1199 // <ConfigHdr> + "&" + <VariableName>
1201 if (IsBufferStorage
) {
1202 Length
= StrLen (Storage
->ConfigHdr
);
1203 Length
+= StrLen (Question
->BlockName
);
1205 Length
= StrLen (Storage
->ConfigHdr
);
1206 Length
+= StrLen (Question
->VariableName
) + 1;
1208 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1209 ASSERT (ConfigRequest
!= NULL
);
1211 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1212 if (IsBufferStorage
) {
1213 StrCat (ConfigRequest
, Question
->BlockName
);
1215 StrCat (ConfigRequest
, L
"&");
1216 StrCat (ConfigRequest
, Question
->VariableName
);
1219 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1220 FormSet
->ConfigAccess
,
1225 if (EFI_ERROR (Status
)) {
1230 // Skip <ConfigRequest>
1232 Value
= Result
+ Length
;
1233 if (IsBufferStorage
) {
1239 if (*Value
!= '=') {
1241 return EFI_NOT_FOUND
;
1244 // Skip '=', point to value
1249 // Suppress <AltResp> if any
1252 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1257 LengthStr
= StrLen (Value
);
1258 Status
= EFI_SUCCESS
;
1259 if (!IsBufferStorage
&& IsString
) {
1261 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1262 // Add string tail char L'\0' into Length
1264 Length
= StorageWidth
+ sizeof (CHAR16
);
1265 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1266 Status
= EFI_BUFFER_TOO_SMALL
;
1268 StringPtr
= (CHAR16
*) Dst
;
1269 ZeroMem (TemStr
, sizeof (TemStr
));
1270 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1271 StrnCpy (TemStr
, Value
+ Index
, 4);
1272 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1275 // Add tailing L'\0' character
1277 StringPtr
[Index
/4] = L
'\0';
1280 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1281 Status
= EFI_BUFFER_TOO_SMALL
;
1283 ZeroMem (TemStr
, sizeof (TemStr
));
1284 for (Index
= 0; Index
< LengthStr
; Index
++) {
1285 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1286 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1287 if ((Index
& 1) == 0) {
1288 Dst
[Index
/2] = DigitUint8
;
1290 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1296 if (EFI_ERROR (Status
)) {
1302 // Synchronize Edit Buffer
1304 if (IsBufferStorage
) {
1305 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1307 SetValueByName (Storage
, Question
->VariableName
, Value
);
1318 Save Question Value to edit copy(cached) or Storage(uncached).
1320 @param FormSet FormSet data structure.
1321 @param Form Form data structure.
1322 @param Question Pointer to the Question.
1323 @param Cached TRUE: set to Edit copy FALSE: set to original
1326 @retval EFI_SUCCESS The function completed successfully.
1331 IN FORM_BROWSER_FORMSET
*FormSet
,
1332 IN FORM_BROWSER_FORM
*Form
,
1333 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1344 FORMSET_STORAGE
*Storage
;
1345 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1350 BOOLEAN IsBufferStorage
;
1357 Status
= EFI_SUCCESS
;
1360 // Statement don't have storage, skip them
1362 if (Question
->QuestionId
== 0) {
1367 // If Question value is provided by an Expression, then it is read only
1369 if (Question
->ValueExpression
!= NULL
) {
1374 // Question value is provided by RTC
1376 Storage
= Question
->Storage
;
1377 QuestionValue
= &Question
->HiiValue
.Value
;
1378 if (Storage
== NULL
) {
1380 // It's a Question without storage, or RTC date/time
1382 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1384 // Date and time define the same Flags bit
1386 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1387 case QF_DATE_STORAGE_TIME
:
1388 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1391 case QF_DATE_STORAGE_WAKEUP
:
1392 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1395 case QF_DATE_STORAGE_NORMAL
:
1398 // For date/time without storage
1403 if (EFI_ERROR (Status
)) {
1407 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1408 EfiTime
.Year
= QuestionValue
->date
.Year
;
1409 EfiTime
.Month
= QuestionValue
->date
.Month
;
1410 EfiTime
.Day
= QuestionValue
->date
.Day
;
1412 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1413 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1414 EfiTime
.Second
= QuestionValue
->time
.Second
;
1417 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1418 Status
= gRT
->SetTime (&EfiTime
);
1420 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1428 // Question value is provided by EFI variable
1430 StorageWidth
= Question
->StorageWidth
;
1431 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1432 if (Question
->BufferValue
!= NULL
) {
1433 Src
= Question
->BufferValue
;
1435 Src
= (UINT8
*) QuestionValue
;
1438 Status
= gRT
->SetVariable (
1439 Question
->VariableName
,
1441 Storage
->Attributes
,
1449 // Question Value is provided by Buffer Storage or NameValue Storage
1451 if (Question
->BufferValue
!= NULL
) {
1452 Src
= Question
->BufferValue
;
1454 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1457 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1458 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1459 if (IsBufferStorage
) {
1461 // Copy to storage edit buffer
1463 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1467 // Allocate enough string buffer.
1470 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1471 Value
= AllocateZeroPool (BufferLen
);
1472 ASSERT (Value
!= NULL
);
1474 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1476 TemName
= (CHAR16
*) Src
;
1478 for (; *TemName
!= L
'\0'; TemName
++) {
1479 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1482 BufferLen
= StorageWidth
* 2 + 1;
1483 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1484 ASSERT (Value
!= NULL
);
1486 // Convert Buffer to Hex String
1488 TemBuffer
= Src
+ StorageWidth
- 1;
1490 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1491 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1495 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
);
1501 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1502 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1504 if (IsBufferStorage
) {
1505 Length
= StrLen (Question
->BlockName
) + 7;
1507 Length
= StrLen (Question
->VariableName
) + 2;
1509 if (!IsBufferStorage
&& IsString
) {
1510 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1512 Length
+= (StorageWidth
* 2);
1514 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1515 ASSERT (ConfigResp
!= NULL
);
1517 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1518 if (IsBufferStorage
) {
1519 StrCat (ConfigResp
, Question
->BlockName
);
1520 StrCat (ConfigResp
, L
"&VALUE=");
1522 StrCat (ConfigResp
, L
"&");
1523 StrCat (ConfigResp
, Question
->VariableName
);
1524 StrCat (ConfigResp
, L
"=");
1527 Value
= ConfigResp
+ StrLen (ConfigResp
);
1529 if (!IsBufferStorage
&& IsString
) {
1531 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1533 TemName
= (CHAR16
*) Src
;
1535 for (; *TemName
!= L
'\0'; TemName
++) {
1536 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1540 // Convert Buffer to Hex String
1542 TemBuffer
= Src
+ StorageWidth
- 1;
1544 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1545 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1550 // Convert to lower char.
1552 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1553 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1554 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1559 // Submit Question Value to Configuration Driver
1561 if (FormSet
->ConfigAccess
!= NULL
) {
1562 Status
= FormSet
->ConfigAccess
->RouteConfig (
1563 FormSet
->ConfigAccess
,
1567 if (EFI_ERROR (Status
)) {
1568 FreePool (ConfigResp
);
1572 FreePool (ConfigResp
);
1575 // Synchronize shadow Buffer
1577 SynchronizeStorage (Storage
);
1585 Perform inconsistent check for a Form.
1587 @param FormSet FormSet data structure.
1588 @param Form Form data structure.
1589 @param Question The Question to be validated.
1590 @param Type Validation type: InConsistent or NoSubmit
1592 @retval EFI_SUCCESS Form validation pass.
1593 @retval other Form validation failed.
1598 IN FORM_BROWSER_FORMSET
*FormSet
,
1599 IN FORM_BROWSER_FORM
*Form
,
1600 IN FORM_BROWSER_STATEMENT
*Question
,
1606 LIST_ENTRY
*ListHead
;
1609 FORM_EXPRESSION
*Expression
;
1611 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1612 ListHead
= &Question
->InconsistentListHead
;
1613 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1614 ListHead
= &Question
->NoSubmitListHead
;
1616 return EFI_UNSUPPORTED
;
1619 Link
= GetFirstNode (ListHead
);
1620 while (!IsNull (ListHead
, Link
)) {
1621 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1624 // Evaluate the expression
1626 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1627 if (EFI_ERROR (Status
)) {
1631 if (Expression
->Result
.Value
.b
) {
1633 // Condition meet, show up error message
1635 if (Expression
->Error
!= 0) {
1636 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1638 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1639 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1643 return EFI_NOT_READY
;
1646 Link
= GetNextNode (ListHead
, Link
);
1654 Perform NoSubmit check for a Form.
1656 @param FormSet FormSet data structure.
1657 @param Form Form data structure.
1659 @retval EFI_SUCCESS Form validation pass.
1660 @retval other Form validation failed.
1665 IN FORM_BROWSER_FORMSET
*FormSet
,
1666 IN FORM_BROWSER_FORM
*Form
1671 FORM_BROWSER_STATEMENT
*Question
;
1673 Link
= GetFirstNode (&Form
->StatementListHead
);
1674 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1675 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1677 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1678 if (EFI_ERROR (Status
)) {
1682 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1692 @param FormSet FormSet data structure.
1693 @param Form Form data structure.
1695 @retval EFI_SUCCESS The function completed successfully.
1700 IN FORM_BROWSER_FORMSET
*FormSet
,
1701 IN FORM_BROWSER_FORM
*Form
1706 EFI_STRING ConfigResp
;
1707 EFI_STRING Progress
;
1708 FORMSET_STORAGE
*Storage
;
1711 // Validate the Form by NoSubmit check
1713 Status
= NoSubmitCheck (FormSet
, Form
);
1714 if (EFI_ERROR (Status
)) {
1719 // Submit Buffer storage or Name/Value storage
1721 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1722 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1723 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1724 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1726 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1731 // Skip if there is no RequestElement
1733 if (Storage
->ElementCount
== 0) {
1738 // Prepare <ConfigResp>
1740 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
1741 if (EFI_ERROR (Status
)) {
1746 // Send <ConfigResp> to Configuration Driver
1748 if (FormSet
->ConfigAccess
!= NULL
) {
1749 Status
= FormSet
->ConfigAccess
->RouteConfig (
1750 FormSet
->ConfigAccess
,
1754 if (EFI_ERROR (Status
)) {
1755 FreePool (ConfigResp
);
1759 FreePool (ConfigResp
);
1762 // Config success, update storage shadow Buffer
1764 SynchronizeStorage (Storage
);
1767 gNvUpdateRequired
= FALSE
;
1774 Reset Question to its default value.
1776 @param FormSet The form set.
1777 @param Form The form.
1778 @param Question The question.
1779 @param DefaultId The Class of the default.
1781 @retval EFI_SUCCESS Question is reset to default value.
1785 GetQuestionDefault (
1786 IN FORM_BROWSER_FORMSET
*FormSet
,
1787 IN FORM_BROWSER_FORM
*Form
,
1788 IN FORM_BROWSER_STATEMENT
*Question
,
1794 QUESTION_DEFAULT
*Default
;
1795 QUESTION_OPTION
*Option
;
1796 EFI_HII_VALUE
*HiiValue
;
1798 EFI_STRING StrValue
;
1800 Status
= EFI_SUCCESS
;
1804 // Statement don't have storage, skip them
1806 if (Question
->QuestionId
== 0) {
1811 // There are three ways to specify default value for a Question:
1812 // 1, use nested EFI_IFR_DEFAULT (highest priority)
1813 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
1814 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
1816 HiiValue
= &Question
->HiiValue
;
1819 // EFI_IFR_DEFAULT has highest priority
1821 if (!IsListEmpty (&Question
->DefaultListHead
)) {
1822 Link
= GetFirstNode (&Question
->DefaultListHead
);
1823 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
1824 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1826 if (Default
->DefaultId
== DefaultId
) {
1827 if (Default
->ValueExpression
!= NULL
) {
1829 // Default is provided by an Expression, evaluate it
1831 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
1832 if (EFI_ERROR (Status
)) {
1836 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1839 // Default value is embedded in EFI_IFR_DEFAULT
1841 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
1844 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1845 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
1846 if (StrValue
== NULL
) {
1847 return EFI_NOT_FOUND
;
1849 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
1855 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
1860 // EFI_ONE_OF_OPTION
1862 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
1863 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1865 // OneOfOption could only provide Standard and Manufacturing default
1867 Link
= GetFirstNode (&Question
->OptionListHead
);
1868 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1869 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1871 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
1872 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
1874 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1879 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1885 // EFI_IFR_CHECKBOX - lowest priority
1887 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
1888 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1890 // Checkbox could only provide Standard and Manufacturing default
1892 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
1893 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
1895 HiiValue
->Value
.b
= TRUE
;
1897 HiiValue
->Value
.b
= FALSE
;
1905 // For Questions without default
1907 switch (Question
->Operand
) {
1908 case EFI_IFR_ONE_OF_OP
:
1910 // Take first oneof option as oneof's default value
1912 if (ValueToOption (Question
, HiiValue
) == NULL
) {
1913 Link
= GetFirstNode (&Question
->OptionListHead
);
1914 if (!IsNull (&Question
->OptionListHead
, Link
)) {
1915 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1916 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1921 case EFI_IFR_ORDERED_LIST_OP
:
1923 // Take option sequence in IFR as ordered list's default value
1926 Link
= GetFirstNode (&Question
->OptionListHead
);
1927 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1928 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1930 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
1933 if (Index
>= Question
->MaxContainers
) {
1937 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1942 Status
= EFI_NOT_FOUND
;
1951 Reset Questions in a Form to their default value.
1953 @param FormSet FormSet data structure.
1954 @param Form The Form which to be reset.
1955 @param DefaultId The Class of the default.
1957 @retval EFI_SUCCESS The function completed successfully.
1961 ExtractFormDefault (
1962 IN FORM_BROWSER_FORMSET
*FormSet
,
1963 IN FORM_BROWSER_FORM
*Form
,
1969 FORM_BROWSER_STATEMENT
*Question
;
1971 Link
= GetFirstNode (&Form
->StatementListHead
);
1972 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1973 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1974 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1977 // If Question is disabled, don't reset it to default
1979 if (Question
->DisableExpression
!= NULL
) {
1980 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
1981 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
1987 // Reset Question to its default value
1989 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
1990 if (EFI_ERROR (Status
)) {
1995 // Synchronize Buffer storage's Edit buffer
1997 if ((Question
->Storage
!= NULL
) &&
1998 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1999 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2007 Initialize Question's Edit copy from Storage.
2009 @param Selection Selection contains the information about
2010 the Selection, form and formset to be displayed.
2011 Selection action may be updated in retrieve callback.
2012 @param FormSet FormSet data structure.
2013 @param Form Form data structure.
2015 @retval EFI_SUCCESS The function completed successfully.
2020 IN OUT UI_MENU_SELECTION
*Selection
,
2021 IN FORM_BROWSER_FORMSET
*FormSet
,
2022 IN FORM_BROWSER_FORM
*Form
2027 FORM_BROWSER_STATEMENT
*Question
;
2030 EFI_HII_VALUE
*HiiValue
;
2031 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2033 Link
= GetFirstNode (&Form
->StatementListHead
);
2034 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2035 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2038 // Initialize local copy of Value for each Question
2040 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2041 if (EFI_ERROR (Status
)) {
2046 // Check whether EfiVarstore with CallBack can be got.
2048 if ((Question
->QuestionId
!= 0) && (Question
->Storage
!= NULL
) &&
2049 (Question
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) &&
2050 ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
2052 // ConfigAccess can't be NULL.
2054 if (FormSet
->ConfigAccess
== NULL
) {
2055 return EFI_UNSUPPORTED
;
2058 // Check QuestionValue does exist.
2060 StorageWidth
= Question
->StorageWidth
;
2061 if (Question
->BufferValue
!= NULL
) {
2062 BufferValue
= Question
->BufferValue
;
2064 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2066 Status
= gRT
->GetVariable (
2067 Question
->VariableName
,
2068 &Question
->Storage
->Guid
,
2074 if (!EFI_ERROR (Status
)) {
2075 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2076 HiiValue
= &Question
->HiiValue
;
2077 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2078 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2080 // Create String in HII database for Configuration Driver to retrieve
2082 HiiValue
->Value
.string
= NewString ((CHAR16
*) Question
->BufferValue
, FormSet
->HiiHandle
);
2083 } else if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2084 BufferValue
= Question
->BufferValue
;
2087 Status
= FormSet
->ConfigAccess
->Callback (
2088 FormSet
->ConfigAccess
,
2089 EFI_BROWSER_ACTION_RETRIEVE
,
2090 Question
->QuestionId
,
2092 (EFI_IFR_TYPE_VALUE
*) BufferValue
,
2096 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2098 // Clean the String in HII Database
2100 DeleteString (HiiValue
->Value
.string
, FormSet
->HiiHandle
);
2103 if (!EFI_ERROR (Status
)) {
2104 switch (ActionRequest
) {
2105 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2106 gResetRequired
= TRUE
;
2109 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2111 // Till now there is no uncommitted data, so ignore this request
2115 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2116 Selection
->Action
= UI_ACTION_EXIT
;
2126 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2133 Initialize Question's Edit copy from Storage for the whole Formset.
2135 @param Selection Selection contains the information about
2136 the Selection, form and formset to be displayed.
2137 Selection action may be updated in retrieve callback.
2138 @param FormSet FormSet data structure.
2140 @retval EFI_SUCCESS The function completed successfully.
2145 IN OUT UI_MENU_SELECTION
*Selection
,
2146 IN FORM_BROWSER_FORMSET
*FormSet
2151 FORM_BROWSER_FORM
*Form
;
2153 Link
= GetFirstNode (&FormSet
->FormListHead
);
2154 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2155 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2158 // Initialize local copy of Value for each Form
2160 Status
= LoadFormConfig (Selection
, FormSet
, Form
);
2161 if (EFI_ERROR (Status
)) {
2165 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2172 Fill storage's edit copy with settings requested from Configuration Driver.
2174 @param FormSet FormSet data structure.
2175 @param Storage Buffer Storage.
2177 @retval EFI_SUCCESS The function completed successfully.
2182 IN FORM_BROWSER_FORMSET
*FormSet
,
2183 IN FORMSET_STORAGE
*Storage
2187 EFI_STRING Progress
;
2191 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2195 if (FormSet
->ConfigAccess
== NULL
) {
2196 return EFI_NOT_FOUND
;
2199 if (Storage
->ElementCount
== 0) {
2201 // Skip if there is no RequestElement
2207 // Request current settings from Configuration Driver
2209 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2210 FormSet
->ConfigAccess
,
2211 Storage
->ConfigRequest
,
2215 if (EFI_ERROR (Status
)) {
2220 // Convert Result from <ConfigAltResp> to <ConfigResp>
2222 StrPtr
= StrStr (Result
, L
"ALTCFG");
2223 if (StrPtr
!= NULL
) {
2227 Status
= ConfigRespToStorage (Storage
, Result
);
2234 Copy uncommitted data from source Storage to destination Storage.
2236 @param Dst Target Storage for uncommitted data.
2237 @param Src Source Storage for uncommitted data.
2239 @retval EFI_SUCCESS The function completed successfully.
2240 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2245 IN OUT FORMSET_STORAGE
*Dst
,
2246 IN FORMSET_STORAGE
*Src
2250 NAME_VALUE_NODE
*Node
;
2252 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2253 return EFI_INVALID_PARAMETER
;
2256 switch (Src
->Type
) {
2257 case EFI_HII_VARSTORE_BUFFER
:
2258 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
2261 case EFI_HII_VARSTORE_NAME_VALUE
:
2262 Link
= GetFirstNode (&Src
->NameValueListHead
);
2263 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
2264 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2266 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
);
2268 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
2272 case EFI_HII_VARSTORE_EFI_VARIABLE
:
2282 Get current setting of Questions.
2284 @param FormSet FormSet data structure.
2286 @retval EFI_SUCCESS The function completed successfully.
2290 InitializeCurrentSetting (
2291 IN OUT FORM_BROWSER_FORMSET
*FormSet
2296 FORMSET_STORAGE
*Storage
;
2297 FORMSET_STORAGE
*StorageSrc
;
2298 FORMSET_STORAGE
*OldStorage
;
2299 FORM_BROWSER_FORM
*Form
;
2303 // Extract default from IFR binary
2305 Link
= GetFirstNode (&FormSet
->FormListHead
);
2306 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2307 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2309 Status
= ExtractFormDefault (FormSet
, Form
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2311 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2315 // Request current settings from Configuration Driver
2317 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2318 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2319 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2322 if (gOldFormSet
!= NULL
) {
2324 // Try to find the Storage in backup formset gOldFormSet
2326 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
2327 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
2328 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
2330 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
2331 OldStorage
= StorageSrc
;
2335 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
2339 if (OldStorage
== NULL
) {
2341 // Storage is not found in backup formset, request it from ConfigDriver
2343 Status
= LoadStorage (FormSet
, Storage
);
2346 // Storage found in backup formset, use it
2348 Status
= CopyStorage (Storage
, OldStorage
);
2352 // Now Edit Buffer is filled with default values(lower priority) and current
2353 // settings(higher priority), sychronize it to shadow Buffer
2355 if (!EFI_ERROR (Status
)) {
2356 SynchronizeStorage (Storage
);
2359 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2367 Fetch the Ifr binary data of a FormSet.
2369 @param Handle PackageList Handle
2370 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2371 specified (NULL or zero GUID), take the first
2372 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2373 found in package list.
2374 On output, GUID of the formset found(if not NULL).
2375 @param BinaryLength The length of the FormSet IFR binary.
2376 @param BinaryData The buffer designed to receive the FormSet.
2378 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
2379 BufferLength was updated.
2380 @retval EFI_INVALID_PARAMETER The handle is unknown.
2381 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
2382 be found with the requested FormId.
2387 IN EFI_HII_HANDLE Handle
,
2388 IN OUT EFI_GUID
*FormSetGuid
,
2389 OUT UINTN
*BinaryLength
,
2390 OUT UINT8
**BinaryData
2394 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2400 UINT32 PackageListLength
;
2401 EFI_HII_PACKAGE_HEADER PackageHeader
;
2403 UINT8 NumberOfClassGuid
;
2404 BOOLEAN ClassGuidMatch
;
2405 EFI_GUID
*ClassGuid
;
2406 EFI_GUID
*ComparingGuid
;
2410 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2413 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
2415 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
2416 ComparingGuid
= &gEfiHiiPlatformSetupFormsetGuid
;
2418 ComparingGuid
= FormSetGuid
;
2422 // Get HII PackageList
2425 HiiPackageList
= NULL
;
2426 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2427 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2428 HiiPackageList
= AllocatePool (BufferSize
);
2429 ASSERT (HiiPackageList
!= NULL
);
2431 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2433 if (EFI_ERROR (Status
)) {
2436 ASSERT (HiiPackageList
!= NULL
);
2439 // Get Form package from this HII package List
2441 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2443 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
2445 ClassGuidMatch
= FALSE
;
2446 while (Offset
< PackageListLength
) {
2447 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
2448 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2450 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
2452 // Search FormSet in this Form Package
2454 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
2455 while (Offset2
< PackageHeader
.Length
) {
2456 OpCodeData
= Package
+ Offset2
;
2458 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
2460 // Try to compare against formset GUID
2462 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2466 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
2468 // Try to compare against formset class GUID
2470 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2471 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
2472 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
2473 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
2474 ClassGuidMatch
= TRUE
;
2478 if (ClassGuidMatch
) {
2481 } else if (ComparingGuid
== &gEfiHiiPlatformSetupFormsetGuid
) {
2482 ClassGuidMatch
= TRUE
;
2487 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
2490 if (Offset2
< PackageHeader
.Length
) {
2492 // Target formset found
2498 Offset
+= PackageHeader
.Length
;
2501 if (Offset
>= PackageListLength
) {
2503 // Form package not found in this Package List
2505 FreePool (HiiPackageList
);
2506 return EFI_NOT_FOUND
;
2509 if (ClassGuidMatch
&& (FormSetGuid
!= NULL
)) {
2511 // Return the FormSet GUID
2513 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2517 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
2518 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
2519 // of the Form Package.
2521 *BinaryLength
= PackageHeader
.Length
- Offset2
;
2522 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
2524 FreePool (HiiPackageList
);
2526 if (*BinaryData
== NULL
) {
2527 return EFI_OUT_OF_RESOURCES
;
2535 Initialize the internal data structure of a FormSet.
2537 @param Handle PackageList Handle
2538 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2539 specified (NULL or zero GUID), take the first
2540 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2541 found in package list.
2542 On output, GUID of the formset found(if not NULL).
2543 @param FormSet FormSet data structure.
2545 @retval EFI_SUCCESS The function completed successfully.
2546 @retval EFI_NOT_FOUND The specified FormSet could not be found.
2551 IN EFI_HII_HANDLE Handle
,
2552 IN OUT EFI_GUID
*FormSetGuid
,
2553 OUT FORM_BROWSER_FORMSET
*FormSet
2557 EFI_HANDLE DriverHandle
;
2560 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
2561 if (EFI_ERROR (Status
)) {
2565 FormSet
->HiiHandle
= Handle
;
2566 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
2569 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
2571 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
2572 if (EFI_ERROR (Status
)) {
2575 FormSet
->DriverHandle
= DriverHandle
;
2576 Status
= gBS
->HandleProtocol (
2578 &gEfiHiiConfigAccessProtocolGuid
,
2579 (VOID
**) &FormSet
->ConfigAccess
2581 if (EFI_ERROR (Status
)) {
2583 // Configuration Driver don't attach ConfigAccess protocol to its HII package
2584 // list, then there will be no configuration action required
2586 FormSet
->ConfigAccess
= NULL
;
2590 // Parse the IFR binary OpCodes
2592 Status
= ParseOpCodes (FormSet
);
2593 if (EFI_ERROR (Status
)) {
2598 // Set VFR type by FormSet SubClass field
2600 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
2601 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2602 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
2606 // Set VFR type by FormSet class guid
2608 for (Index
= 0; Index
< 3; Index
++) {
2609 if (CompareGuid (&FormSet
->ClassGuid
[Index
], &gEfiHiiPlatformSetupFormsetGuid
)) {
2610 gClassOfVfr
|= FORMSET_CLASS_PLATFORM_SETUP
;
2615 if ((gClassOfVfr
& FORMSET_CLASS_FRONT_PAGE
) == FORMSET_CLASS_FRONT_PAGE
) {
2616 gFrontPageHandle
= FormSet
->HiiHandle
;
2620 // Match GUID to find out the function key setting. If match fail, use the default setting.
2622 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
2623 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
2625 // Update the function key setting.
2627 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
2629 // Function key prompt can not be displayed if the function key has been disabled.
2631 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2632 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2635 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2636 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2646 Save globals used by previous call to SendForm(). SendForm() may be called from
2647 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
2648 So, save globals of previous call to SendForm() and restore them upon exit.
2652 SaveBrowserContext (
2656 BROWSER_CONTEXT
*Context
;
2658 gBrowserContextCount
++;
2659 if (gBrowserContextCount
== 1) {
2661 // This is not reentry of SendForm(), no context to save
2666 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
2667 ASSERT (Context
!= NULL
);
2669 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
2672 // Save FormBrowser context
2674 Context
->BannerData
= gBannerData
;
2675 Context
->ClassOfVfr
= gClassOfVfr
;
2676 Context
->FunctionKeySetting
= gFunctionKeySetting
;
2677 Context
->ResetRequired
= gResetRequired
;
2678 Context
->NvUpdateRequired
= gNvUpdateRequired
;
2679 Context
->Direction
= gDirection
;
2680 Context
->FunctionNineString
= gFunctionNineString
;
2681 Context
->FunctionTenString
= gFunctionTenString
;
2682 Context
->EnterString
= gEnterString
;
2683 Context
->EnterCommitString
= gEnterCommitString
;
2684 Context
->EnterEscapeString
= gEnterEscapeString
;
2685 Context
->EscapeString
= gEscapeString
;
2686 Context
->SaveFailed
= gSaveFailed
;
2687 Context
->MoveHighlight
= gMoveHighlight
;
2688 Context
->MakeSelection
= gMakeSelection
;
2689 Context
->DecNumericInput
= gDecNumericInput
;
2690 Context
->HexNumericInput
= gHexNumericInput
;
2691 Context
->ToggleCheckBox
= gToggleCheckBox
;
2692 Context
->PromptForData
= gPromptForData
;
2693 Context
->PromptForPassword
= gPromptForPassword
;
2694 Context
->PromptForNewPassword
= gPromptForNewPassword
;
2695 Context
->ConfirmPassword
= gConfirmPassword
;
2696 Context
->ConfirmError
= gConfirmError
;
2697 Context
->PassowordInvalid
= gPassowordInvalid
;
2698 Context
->PressEnter
= gPressEnter
;
2699 Context
->EmptyString
= gEmptyString
;
2700 Context
->AreYouSure
= gAreYouSure
;
2701 Context
->YesResponse
= gYesResponse
;
2702 Context
->NoResponse
= gNoResponse
;
2703 Context
->MiniString
= gMiniString
;
2704 Context
->PlusString
= gPlusString
;
2705 Context
->MinusString
= gMinusString
;
2706 Context
->AdjustNumber
= gAdjustNumber
;
2707 Context
->SaveChanges
= gSaveChanges
;
2708 Context
->OptionMismatch
= gOptionMismatch
;
2709 Context
->FormSuppress
= gFormSuppress
;
2710 Context
->PromptBlockWidth
= gPromptBlockWidth
;
2711 Context
->OptionBlockWidth
= gOptionBlockWidth
;
2712 Context
->HelpBlockWidth
= gHelpBlockWidth
;
2713 Context
->OldFormSet
= gOldFormSet
;
2714 Context
->MenuRefreshHead
= gMenuRefreshHead
;
2716 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
2717 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
2720 // Insert to FormBrowser context list
2722 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
2727 Restore globals used by previous call to SendForm().
2731 RestoreBrowserContext (
2736 BROWSER_CONTEXT
*Context
;
2738 ASSERT (gBrowserContextCount
!= 0);
2739 gBrowserContextCount
--;
2740 if (gBrowserContextCount
== 0) {
2742 // This is not reentry of SendForm(), no context to restore
2747 ASSERT (!IsListEmpty (&gBrowserContextList
));
2749 Link
= GetFirstNode (&gBrowserContextList
);
2750 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
2753 // Restore FormBrowser context
2755 gBannerData
= Context
->BannerData
;
2756 gClassOfVfr
= Context
->ClassOfVfr
;
2757 gFunctionKeySetting
= Context
->FunctionKeySetting
;
2758 gResetRequired
= Context
->ResetRequired
;
2759 gNvUpdateRequired
= Context
->NvUpdateRequired
;
2760 gDirection
= Context
->Direction
;
2761 gFunctionNineString
= Context
->FunctionNineString
;
2762 gFunctionTenString
= Context
->FunctionTenString
;
2763 gEnterString
= Context
->EnterString
;
2764 gEnterCommitString
= Context
->EnterCommitString
;
2765 gEnterEscapeString
= Context
->EnterEscapeString
;
2766 gEscapeString
= Context
->EscapeString
;
2767 gSaveFailed
= Context
->SaveFailed
;
2768 gMoveHighlight
= Context
->MoveHighlight
;
2769 gMakeSelection
= Context
->MakeSelection
;
2770 gDecNumericInput
= Context
->DecNumericInput
;
2771 gHexNumericInput
= Context
->HexNumericInput
;
2772 gToggleCheckBox
= Context
->ToggleCheckBox
;
2773 gPromptForData
= Context
->PromptForData
;
2774 gPromptForPassword
= Context
->PromptForPassword
;
2775 gPromptForNewPassword
= Context
->PromptForNewPassword
;
2776 gConfirmPassword
= Context
->ConfirmPassword
;
2777 gConfirmError
= Context
->ConfirmError
;
2778 gPassowordInvalid
= Context
->PassowordInvalid
;
2779 gPressEnter
= Context
->PressEnter
;
2780 gEmptyString
= Context
->EmptyString
;
2781 gAreYouSure
= Context
->AreYouSure
;
2782 gYesResponse
= Context
->YesResponse
;
2783 gNoResponse
= Context
->NoResponse
;
2784 gMiniString
= Context
->MiniString
;
2785 gPlusString
= Context
->PlusString
;
2786 gMinusString
= Context
->MinusString
;
2787 gAdjustNumber
= Context
->AdjustNumber
;
2788 gSaveChanges
= Context
->SaveChanges
;
2789 gOptionMismatch
= Context
->OptionMismatch
;
2790 gFormSuppress
= Context
->FormSuppress
;
2791 gPromptBlockWidth
= Context
->PromptBlockWidth
;
2792 gOptionBlockWidth
= Context
->OptionBlockWidth
;
2793 gHelpBlockWidth
= Context
->HelpBlockWidth
;
2794 gOldFormSet
= Context
->OldFormSet
;
2795 gMenuRefreshHead
= Context
->MenuRefreshHead
;
2797 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
2798 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
2801 // Remove from FormBrowser context list
2803 RemoveEntryList (&Context
->Link
);
2804 gBS
->FreePool (Context
);