2 Entry and initialization module for the browser.
4 Copyright (c) 2007 - 2009, 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
;
280 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
283 // Ensure we are in Text mode
285 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
287 for (Index
= 0; Index
< HandleCount
; Index
++) {
288 Selection
= AllocateZeroPool (sizeof (UI_MENU_SELECTION
));
289 ASSERT (Selection
!= NULL
);
291 Selection
->Handle
= Handles
[Index
];
292 if (FormSetGuid
!= NULL
) {
293 CopyMem (&Selection
->FormSetGuid
, FormSetGuid
, sizeof (EFI_GUID
));
294 Selection
->FormId
= FormId
;
298 gNvUpdateRequired
= FALSE
;
301 FormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
302 ASSERT (FormSet
!= NULL
);
305 // Initialize internal data structures of FormSet
307 Status
= InitializeFormSet (Selection
->Handle
, &Selection
->FormSetGuid
, FormSet
);
308 if (EFI_ERROR (Status
) || IsListEmpty (&FormSet
->FormListHead
)) {
309 DestroyFormSet (FormSet
);
312 Selection
->FormSet
= FormSet
;
315 // Display this formset
317 gCurrentSelection
= Selection
;
319 Status
= SetupBrowser (Selection
);
321 gCurrentSelection
= NULL
;
323 if (EFI_ERROR (Status
)) {
327 } while (Selection
->Action
== UI_ACTION_REFRESH_FORMSET
);
329 if (gOldFormSet
!= NULL
) {
330 DestroyFormSet (gOldFormSet
);
334 FreePool (Selection
);
337 if (ActionRequest
!= NULL
) {
338 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
339 if (gResetRequired
) {
340 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
344 FreeBrowserStrings ();
346 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
347 gST
->ConOut
->ClearScreen (gST
->ConOut
);
351 // Restore globals used by SendForm()
353 RestoreBrowserContext ();
360 This function is called by a callback handler to retrieve uncommitted state
361 data from the browser.
363 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
365 @param ResultsDataSize A pointer to the size of the buffer associated
367 @param ResultsData A string returned from an IFR browser or
368 equivalent. The results string will have no
369 routing information in them.
370 @param RetrieveData A BOOLEAN field which allows an agent to retrieve
371 (if RetrieveData = TRUE) data from the uncommitted
372 browser state information or set (if RetrieveData
373 = FALSE) data in the uncommitted browser state
375 @param VariableGuid An optional field to indicate the target variable
377 @param VariableName An optional field to indicate the target
378 human-readable variable name.
380 @retval EFI_SUCCESS The results have been distributed or are awaiting
382 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to
383 contain the results data.
389 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
390 IN OUT UINTN
*ResultsDataSize
,
391 IN OUT EFI_STRING ResultsData
,
392 IN BOOLEAN RetrieveData
,
393 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
394 IN CONST CHAR16
*VariableName OPTIONAL
399 FORMSET_STORAGE
*Storage
;
400 FORM_BROWSER_FORMSET
*FormSet
;
407 if (ResultsDataSize
== NULL
|| ResultsData
== NULL
) {
408 return EFI_INVALID_PARAMETER
;
411 if (gCurrentSelection
== NULL
) {
412 return EFI_NOT_READY
;
417 FormSet
= gCurrentSelection
->FormSet
;
420 // Find target storage
422 Link
= GetFirstNode (&FormSet
->StorageListHead
);
423 if (IsNull (&FormSet
->StorageListHead
, Link
)) {
424 return EFI_UNSUPPORTED
;
427 if (VariableGuid
!= NULL
) {
429 // Try to find target storage
432 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
433 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
434 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
436 if (CompareGuid (&Storage
->Guid
, (EFI_GUID
*) VariableGuid
)) {
437 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
439 // Buffer storage require both GUID and Name
441 if (VariableName
== NULL
) {
442 return EFI_NOT_FOUND
;
445 if (StrCmp (Storage
->Name
, (CHAR16
*) VariableName
) != 0) {
455 return EFI_NOT_FOUND
;
459 // GUID/Name is not specified, take the first storage in FormSet
461 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
466 // Skip if there is no RequestElement
468 if (Storage
->ElementCount
== 0) {
473 // Generate <ConfigResp>
475 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
476 if (EFI_ERROR (Status
)) {
481 // Skip <ConfigHdr> and '&' to point to <ConfigBody>
483 StrPtr
= ConfigResp
+ StrLen (Storage
->ConfigHdr
) + 1;
485 BufferSize
= StrSize (StrPtr
);
486 if (*ResultsDataSize
< BufferSize
) {
487 *ResultsDataSize
= BufferSize
;
489 FreePool (ConfigResp
);
490 return EFI_BUFFER_TOO_SMALL
;
493 *ResultsDataSize
= BufferSize
;
494 CopyMem (ResultsData
, StrPtr
, BufferSize
);
496 FreePool (ConfigResp
);
499 // Prepare <ConfigResp>
501 TmpSize
= StrLen (ResultsData
);
502 BufferSize
= (TmpSize
+ StrLen (Storage
->ConfigHdr
) + 2) * sizeof (CHAR16
);
503 ConfigResp
= AllocateZeroPool (BufferSize
);
504 ASSERT (ConfigResp
!= NULL
);
506 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
507 StrCat (ConfigResp
, L
"&");
508 StrCat (ConfigResp
, ResultsData
);
511 // Update Browser uncommited data
513 Status
= ConfigRespToStorage (Storage
, ConfigResp
);
514 if (EFI_ERROR (Status
)) {
524 Initialize Setup Browser driver.
526 @param ImageHandle The image handle.
527 @param SystemTable The system table.
529 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
530 @return Other value if failed to initialize the Setup Browser module.
536 IN EFI_HANDLE ImageHandle
,
537 IN EFI_SYSTEM_TABLE
*SystemTable
543 // Locate required Hii relative protocols
545 Status
= gBS
->LocateProtocol (
546 &gEfiHiiDatabaseProtocolGuid
,
548 (VOID
**) &mHiiDatabase
550 ASSERT_EFI_ERROR (Status
);
552 Status
= gBS
->LocateProtocol (
553 &gEfiHiiStringProtocolGuid
,
555 (VOID
**) &mHiiString
557 ASSERT_EFI_ERROR (Status
);
559 Status
= gBS
->LocateProtocol (
560 &gEfiHiiConfigRoutingProtocolGuid
,
562 (VOID
**) &mHiiConfigRouting
564 ASSERT_EFI_ERROR (Status
);
567 // Publish our HII data
569 gHiiHandle
= HiiAddPackages (
575 ASSERT (gHiiHandle
!= NULL
);
578 // Initialize Driver private data
580 gBannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
581 ASSERT (gBannerData
!= NULL
);
584 // Install FormBrowser2 protocol
586 mPrivateData
.Handle
= NULL
;
587 Status
= gBS
->InstallProtocolInterface (
588 &mPrivateData
.Handle
,
589 &gEfiFormBrowser2ProtocolGuid
,
590 EFI_NATIVE_INTERFACE
,
591 &mPrivateData
.FormBrowser2
593 ASSERT_EFI_ERROR (Status
);
600 Create a new string in HII Package List.
602 @param String The String to be added
603 @param HiiHandle The package list in the HII database to insert the
606 @return The output string.
612 IN EFI_HII_HANDLE HiiHandle
615 EFI_STRING_ID StringId
;
617 StringId
= HiiSetString (HiiHandle
, 0, String
, NULL
);
618 ASSERT (StringId
!= 0);
625 Delete a string from HII Package List.
627 @param StringId Id of the string in HII database.
628 @param HiiHandle The HII package list handle.
630 @retval EFI_SUCCESS The string was deleted successfully.
635 IN EFI_STRING_ID StringId
,
636 IN EFI_HII_HANDLE HiiHandle
641 NullChar
= CHAR_NULL
;
642 HiiSetString (HiiHandle
, StringId
, &NullChar
, NULL
);
648 Get the string based on the StringId and HII Package List Handle.
650 @param Token The String's ID.
651 @param HiiHandle The package list in the HII database to search for
652 the specified string.
654 @return The output string.
659 IN EFI_STRING_ID Token
,
660 IN EFI_HII_HANDLE HiiHandle
665 String
= HiiGetString (HiiHandle
, Token
, NULL
);
666 if (String
== NULL
) {
667 String
= AllocateCopyPool (sizeof (mUnknownString
), mUnknownString
);
668 ASSERT (String
!= NULL
);
670 return (CHAR16
*) String
;
675 Allocate new memory and then copy the Unicode string Source to Destination.
677 @param Dest Location to copy string
678 @param Src String to copy
683 IN OUT CHAR16
**Dest
,
690 *Dest
= AllocateCopyPool (StrSize (Src
), Src
);
691 ASSERT (*Dest
!= NULL
);
696 Allocate new memory and concatinate Source on the end of Destination.
698 @param Dest String to added to the end of.
699 @param Src String to concatinate.
704 IN OUT CHAR16
**Dest
,
712 NewStringCpy (Dest
, Src
);
716 TmpSize
= StrSize (*Dest
);
717 NewString
= AllocateZeroPool (TmpSize
+ StrSize (Src
) - 1);
718 ASSERT (NewString
!= NULL
);
720 StrCpy (NewString
, *Dest
);
721 StrCat (NewString
, Src
);
729 Synchronize Storage's Edit copy to Shadow copy.
731 @param Storage The Storage to be synchronized.
736 IN FORMSET_STORAGE
*Storage
740 NAME_VALUE_NODE
*Node
;
742 switch (Storage
->Type
) {
743 case EFI_HII_VARSTORE_BUFFER
:
744 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
747 case EFI_HII_VARSTORE_NAME_VALUE
:
748 Link
= GetFirstNode (&Storage
->NameValueListHead
);
749 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
750 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
752 NewStringCpy (&Node
->Value
, Node
->EditValue
);
754 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
758 case EFI_HII_VARSTORE_EFI_VARIABLE
:
766 Get Value for given Name from a NameValue Storage.
768 @param Storage The NameValue Storage.
769 @param Name The Name.
770 @param Value The retured Value.
772 @retval EFI_SUCCESS Value found for given Name.
773 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
778 IN FORMSET_STORAGE
*Storage
,
780 IN OUT CHAR16
**Value
784 NAME_VALUE_NODE
*Node
;
788 Link
= GetFirstNode (&Storage
->NameValueListHead
);
789 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
790 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
792 if (StrCmp (Name
, Node
->Name
) == 0) {
793 NewStringCpy (Value
, Node
->EditValue
);
797 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
800 return EFI_NOT_FOUND
;
805 Set Value of given Name in a NameValue Storage.
807 @param Storage The NameValue Storage.
808 @param Name The Name.
809 @param Value The Value to set.
811 @retval EFI_SUCCESS Value found for given Name.
812 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
817 IN FORMSET_STORAGE
*Storage
,
823 NAME_VALUE_NODE
*Node
;
825 Link
= GetFirstNode (&Storage
->NameValueListHead
);
826 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
827 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
829 if (StrCmp (Name
, Node
->Name
) == 0) {
830 if (Node
->EditValue
!= NULL
) {
831 FreePool (Node
->EditValue
);
833 Node
->EditValue
= AllocateCopyPool (StrSize (Value
), Value
);
834 ASSERT (Node
->EditValue
!= NULL
);
838 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
841 return EFI_NOT_FOUND
;
846 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
848 @param Storage The Storage to be conveted.
849 @param ConfigResp The returned <ConfigResp>.
851 @retval EFI_SUCCESS Convert success.
852 @retval EFI_INVALID_PARAMETER Incorrect storage type.
856 StorageToConfigResp (
857 IN FORMSET_STORAGE
*Storage
,
858 IN CHAR16
**ConfigResp
864 NAME_VALUE_NODE
*Node
;
866 Status
= EFI_SUCCESS
;
868 switch (Storage
->Type
) {
869 case EFI_HII_VARSTORE_BUFFER
:
870 Status
= mHiiConfigRouting
->BlockToConfig (
872 Storage
->ConfigRequest
,
880 case EFI_HII_VARSTORE_NAME_VALUE
:
882 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
884 Link
= GetFirstNode (&Storage
->NameValueListHead
);
885 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
886 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
888 NewStringCat (ConfigResp
, L
"&");
889 NewStringCat (ConfigResp
, Node
->Name
);
890 NewStringCat (ConfigResp
, L
"=");
891 NewStringCat (ConfigResp
, Node
->EditValue
);
893 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
897 case EFI_HII_VARSTORE_EFI_VARIABLE
:
899 Status
= EFI_INVALID_PARAMETER
;
908 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
910 @param Storage The Storage to receive the settings.
911 @param ConfigResp The <ConfigResp> to be converted.
913 @retval EFI_SUCCESS Convert success.
914 @retval EFI_INVALID_PARAMETER Incorrect storage type.
918 ConfigRespToStorage (
919 IN FORMSET_STORAGE
*Storage
,
920 IN CHAR16
*ConfigResp
930 Status
= EFI_SUCCESS
;
932 switch (Storage
->Type
) {
933 case EFI_HII_VARSTORE_BUFFER
:
934 BufferSize
= Storage
->Size
;
935 Status
= mHiiConfigRouting
->ConfigToBlock (
944 case EFI_HII_VARSTORE_NAME_VALUE
:
945 StrPtr
= StrStr (ConfigResp
, L
"&");
946 while (StrPtr
!= NULL
) {
952 StrPtr
= StrStr (StrPtr
, L
"=");
953 if (StrPtr
== NULL
) {
963 StrPtr
= StrStr (StrPtr
, L
"&");
964 if (StrPtr
!= NULL
) {
967 SetValueByName (Storage
, Name
, Value
);
971 case EFI_HII_VARSTORE_EFI_VARIABLE
:
973 Status
= EFI_INVALID_PARAMETER
;
982 Get Question's current Value.
984 @param FormSet FormSet data structure.
985 @param Form Form data structure.
986 @param Question Question to be initialized.
987 @param Cached TRUE: get from Edit copy FALSE: get from original
990 @retval EFI_SUCCESS The function completed successfully.
995 IN FORM_BROWSER_FORMSET
*FormSet
,
996 IN FORM_BROWSER_FORM
*Form
,
997 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1007 FORMSET_STORAGE
*Storage
;
1008 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1009 CHAR16
*ConfigRequest
;
1017 BOOLEAN IsBufferStorage
;
1022 Status
= EFI_SUCCESS
;
1025 // Statement don't have storage, skip them
1027 if (Question
->QuestionId
== 0) {
1032 // Question value is provided by an Expression, evaluate it
1034 if (Question
->ValueExpression
!= NULL
) {
1035 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1036 if (!EFI_ERROR (Status
)) {
1037 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1043 // Question value is provided by RTC
1045 Storage
= Question
->Storage
;
1046 QuestionValue
= &Question
->HiiValue
.Value
;
1047 if (Storage
== NULL
) {
1049 // It's a Question without storage, or RTC date/time
1051 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1053 // Date and time define the same Flags bit
1055 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1056 case QF_DATE_STORAGE_TIME
:
1057 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1060 case QF_DATE_STORAGE_WAKEUP
:
1061 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1064 case QF_DATE_STORAGE_NORMAL
:
1067 // For date/time without storage
1072 if (EFI_ERROR (Status
)) {
1076 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1077 QuestionValue
->date
.Year
= EfiTime
.Year
;
1078 QuestionValue
->date
.Month
= EfiTime
.Month
;
1079 QuestionValue
->date
.Day
= EfiTime
.Day
;
1081 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1082 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1083 QuestionValue
->time
.Second
= EfiTime
.Second
;
1091 // Question value is provided by EFI variable
1093 StorageWidth
= Question
->StorageWidth
;
1094 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1095 if (Question
->BufferValue
!= NULL
) {
1096 Dst
= Question
->BufferValue
;
1098 Dst
= (UINT8
*) QuestionValue
;
1101 Status
= gRT
->GetVariable (
1102 Question
->VariableName
,
1109 // Always return success, even this EFI variable doesn't exist
1115 // Question Value is provided by Buffer Storage or NameValue Storage
1117 if (Question
->BufferValue
!= NULL
) {
1119 // This Question is password or orderedlist
1121 Dst
= Question
->BufferValue
;
1124 // Other type of Questions
1126 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1129 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1130 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1132 if (IsBufferStorage
) {
1134 // Copy from storage Edit buffer
1136 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1138 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1139 if (EFI_ERROR (Status
)) {
1143 LengthStr
= StrLen (Value
);
1144 Status
= EFI_SUCCESS
;
1147 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1148 // Add string tail char L'\0' into Length
1150 Length
= StorageWidth
+ sizeof (CHAR16
);
1151 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1152 Status
= EFI_BUFFER_TOO_SMALL
;
1154 StringPtr
= (CHAR16
*) Dst
;
1155 ZeroMem (TemStr
, sizeof (TemStr
));
1156 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1157 StrnCpy (TemStr
, Value
+ Index
, 4);
1158 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1161 // Add tailing L'\0' character
1163 StringPtr
[Index
/4] = L
'\0';
1166 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1167 Status
= EFI_BUFFER_TOO_SMALL
;
1169 ZeroMem (TemStr
, sizeof (TemStr
));
1170 for (Index
= 0; Index
< LengthStr
; Index
++) {
1171 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1172 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1173 if ((Index
& 1) == 0) {
1174 Dst
[Index
/2] = DigitUint8
;
1176 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1186 // Request current settings from Configuration Driver
1188 if (FormSet
->ConfigAccess
== NULL
) {
1189 return EFI_NOT_FOUND
;
1193 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1194 // <ConfigHdr> + "&" + <VariableName>
1196 if (IsBufferStorage
) {
1197 Length
= StrLen (Storage
->ConfigHdr
);
1198 Length
+= StrLen (Question
->BlockName
);
1200 Length
= StrLen (Storage
->ConfigHdr
);
1201 Length
+= StrLen (Question
->VariableName
) + 1;
1203 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1204 ASSERT (ConfigRequest
!= NULL
);
1206 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1207 if (IsBufferStorage
) {
1208 StrCat (ConfigRequest
, Question
->BlockName
);
1210 StrCat (ConfigRequest
, L
"&");
1211 StrCat (ConfigRequest
, Question
->VariableName
);
1214 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1215 FormSet
->ConfigAccess
,
1220 if (EFI_ERROR (Status
)) {
1225 // Skip <ConfigRequest>
1227 Value
= Result
+ Length
;
1228 if (IsBufferStorage
) {
1234 if (*Value
!= '=') {
1236 return EFI_NOT_FOUND
;
1239 // Skip '=', point to value
1244 // Suppress <AltResp> if any
1247 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1252 LengthStr
= StrLen (Value
);
1253 Status
= EFI_SUCCESS
;
1254 if (!IsBufferStorage
&& IsString
) {
1256 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1257 // Add string tail char L'\0' into Length
1259 Length
= StorageWidth
+ sizeof (CHAR16
);
1260 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1261 Status
= EFI_BUFFER_TOO_SMALL
;
1263 StringPtr
= (CHAR16
*) Dst
;
1264 ZeroMem (TemStr
, sizeof (TemStr
));
1265 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1266 StrnCpy (TemStr
, Value
+ Index
, 4);
1267 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1270 // Add tailing L'\0' character
1272 StringPtr
[Index
/4] = L
'\0';
1275 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1276 Status
= EFI_BUFFER_TOO_SMALL
;
1278 ZeroMem (TemStr
, sizeof (TemStr
));
1279 for (Index
= 0; Index
< LengthStr
; Index
++) {
1280 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1281 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1282 if ((Index
& 1) == 0) {
1283 Dst
[Index
/2] = DigitUint8
;
1285 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1291 if (EFI_ERROR (Status
)) {
1297 // Synchronize Edit Buffer
1299 if (IsBufferStorage
) {
1300 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1302 SetValueByName (Storage
, Question
->VariableName
, Value
);
1313 Save Question Value to edit copy(cached) or Storage(uncached).
1315 @param FormSet FormSet data structure.
1316 @param Form Form data structure.
1317 @param Question Pointer to the Question.
1318 @param Cached TRUE: set to Edit copy FALSE: set to original
1321 @retval EFI_SUCCESS The function completed successfully.
1326 IN FORM_BROWSER_FORMSET
*FormSet
,
1327 IN FORM_BROWSER_FORM
*Form
,
1328 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1339 FORMSET_STORAGE
*Storage
;
1340 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1345 BOOLEAN IsBufferStorage
;
1352 Status
= EFI_SUCCESS
;
1355 // Statement don't have storage, skip them
1357 if (Question
->QuestionId
== 0) {
1362 // If Question value is provided by an Expression, then it is read only
1364 if (Question
->ValueExpression
!= NULL
) {
1369 // Question value is provided by RTC
1371 Storage
= Question
->Storage
;
1372 QuestionValue
= &Question
->HiiValue
.Value
;
1373 if (Storage
== NULL
) {
1375 // It's a Question without storage, or RTC date/time
1377 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1379 // Date and time define the same Flags bit
1381 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1382 case QF_DATE_STORAGE_TIME
:
1383 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1386 case QF_DATE_STORAGE_WAKEUP
:
1387 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1390 case QF_DATE_STORAGE_NORMAL
:
1393 // For date/time without storage
1398 if (EFI_ERROR (Status
)) {
1402 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1403 EfiTime
.Year
= QuestionValue
->date
.Year
;
1404 EfiTime
.Month
= QuestionValue
->date
.Month
;
1405 EfiTime
.Day
= QuestionValue
->date
.Day
;
1407 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1408 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1409 EfiTime
.Second
= QuestionValue
->time
.Second
;
1412 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1413 Status
= gRT
->SetTime (&EfiTime
);
1415 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1423 // Question value is provided by EFI variable
1425 StorageWidth
= Question
->StorageWidth
;
1426 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1427 if (Question
->BufferValue
!= NULL
) {
1428 Src
= Question
->BufferValue
;
1430 Src
= (UINT8
*) QuestionValue
;
1433 Status
= gRT
->SetVariable (
1434 Question
->VariableName
,
1436 Storage
->Attributes
,
1444 // Question Value is provided by Buffer Storage or NameValue Storage
1446 if (Question
->BufferValue
!= NULL
) {
1447 Src
= Question
->BufferValue
;
1449 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1452 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1453 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1454 if (IsBufferStorage
) {
1456 // Copy to storage edit buffer
1458 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1462 // Allocate enough string buffer.
1465 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1466 Value
= AllocateZeroPool (BufferLen
);
1467 ASSERT (Value
!= NULL
);
1469 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1471 TemName
= (CHAR16
*) Src
;
1473 for (; *TemName
!= L
'\0'; TemName
++) {
1474 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1477 BufferLen
= StorageWidth
* 2 + 1;
1478 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1479 ASSERT (Value
!= NULL
);
1481 // Convert Buffer to Hex String
1483 TemBuffer
= Src
+ StorageWidth
- 1;
1485 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1486 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1490 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
);
1496 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1497 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1499 if (IsBufferStorage
) {
1500 Length
= StrLen (Question
->BlockName
) + 7;
1502 Length
= StrLen (Question
->VariableName
) + 2;
1504 if (!IsBufferStorage
&& IsString
) {
1505 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1507 Length
+= (StorageWidth
* 2);
1509 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1510 ASSERT (ConfigResp
!= NULL
);
1512 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1513 if (IsBufferStorage
) {
1514 StrCat (ConfigResp
, Question
->BlockName
);
1515 StrCat (ConfigResp
, L
"&VALUE=");
1517 StrCat (ConfigResp
, L
"&");
1518 StrCat (ConfigResp
, Question
->VariableName
);
1519 StrCat (ConfigResp
, L
"=");
1522 Value
= ConfigResp
+ StrLen (ConfigResp
);
1524 if (!IsBufferStorage
&& IsString
) {
1526 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1528 TemName
= (CHAR16
*) Src
;
1530 for (; *TemName
!= L
'\0'; TemName
++) {
1531 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1535 // Convert Buffer to Hex String
1537 TemBuffer
= Src
+ StorageWidth
- 1;
1539 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1540 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1545 // Convert to lower char.
1547 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1548 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1549 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1554 // Submit Question Value to Configuration Driver
1556 if (FormSet
->ConfigAccess
!= NULL
) {
1557 Status
= FormSet
->ConfigAccess
->RouteConfig (
1558 FormSet
->ConfigAccess
,
1562 if (EFI_ERROR (Status
)) {
1563 FreePool (ConfigResp
);
1567 FreePool (ConfigResp
);
1570 // Synchronize shadow Buffer
1572 SynchronizeStorage (Storage
);
1580 Perform inconsistent check for a Form.
1582 @param FormSet FormSet data structure.
1583 @param Form Form data structure.
1584 @param Question The Question to be validated.
1585 @param Type Validation type: InConsistent or NoSubmit
1587 @retval EFI_SUCCESS Form validation pass.
1588 @retval other Form validation failed.
1593 IN FORM_BROWSER_FORMSET
*FormSet
,
1594 IN FORM_BROWSER_FORM
*Form
,
1595 IN FORM_BROWSER_STATEMENT
*Question
,
1601 LIST_ENTRY
*ListHead
;
1604 FORM_EXPRESSION
*Expression
;
1606 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1607 ListHead
= &Question
->InconsistentListHead
;
1608 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1609 ListHead
= &Question
->NoSubmitListHead
;
1611 return EFI_UNSUPPORTED
;
1614 Link
= GetFirstNode (ListHead
);
1615 while (!IsNull (ListHead
, Link
)) {
1616 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1619 // Evaluate the expression
1621 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1622 if (EFI_ERROR (Status
)) {
1626 if (Expression
->Result
.Value
.b
) {
1628 // Condition meet, show up error message
1630 if (Expression
->Error
!= 0) {
1631 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1633 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1634 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1638 return EFI_NOT_READY
;
1641 Link
= GetNextNode (ListHead
, Link
);
1649 Perform NoSubmit check for a Form.
1651 @param FormSet FormSet data structure.
1652 @param Form Form data structure.
1654 @retval EFI_SUCCESS Form validation pass.
1655 @retval other Form validation failed.
1660 IN FORM_BROWSER_FORMSET
*FormSet
,
1661 IN FORM_BROWSER_FORM
*Form
1666 FORM_BROWSER_STATEMENT
*Question
;
1668 Link
= GetFirstNode (&Form
->StatementListHead
);
1669 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1670 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1672 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1673 if (EFI_ERROR (Status
)) {
1677 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1687 @param FormSet FormSet data structure.
1688 @param Form Form data structure.
1690 @retval EFI_SUCCESS The function completed successfully.
1695 IN FORM_BROWSER_FORMSET
*FormSet
,
1696 IN FORM_BROWSER_FORM
*Form
1701 EFI_STRING ConfigResp
;
1702 EFI_STRING Progress
;
1703 FORMSET_STORAGE
*Storage
;
1706 // Validate the Form by NoSubmit check
1708 Status
= NoSubmitCheck (FormSet
, Form
);
1709 if (EFI_ERROR (Status
)) {
1714 // Submit Buffer storage or Name/Value storage
1716 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1717 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1718 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1719 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1721 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1726 // Skip if there is no RequestElement
1728 if (Storage
->ElementCount
== 0) {
1733 // Prepare <ConfigResp>
1735 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
1736 if (EFI_ERROR (Status
)) {
1741 // Send <ConfigResp> to Configuration Driver
1743 if (FormSet
->ConfigAccess
!= NULL
) {
1744 Status
= FormSet
->ConfigAccess
->RouteConfig (
1745 FormSet
->ConfigAccess
,
1749 if (EFI_ERROR (Status
)) {
1750 FreePool (ConfigResp
);
1754 FreePool (ConfigResp
);
1757 // Config success, update storage shadow Buffer
1759 SynchronizeStorage (Storage
);
1762 gNvUpdateRequired
= FALSE
;
1769 Reset Question to its default value.
1771 @param FormSet The form set.
1772 @param Form The form.
1773 @param Question The question.
1774 @param DefaultId The Class of the default.
1776 @retval EFI_SUCCESS Question is reset to default value.
1780 GetQuestionDefault (
1781 IN FORM_BROWSER_FORMSET
*FormSet
,
1782 IN FORM_BROWSER_FORM
*Form
,
1783 IN FORM_BROWSER_STATEMENT
*Question
,
1789 QUESTION_DEFAULT
*Default
;
1790 QUESTION_OPTION
*Option
;
1791 EFI_HII_VALUE
*HiiValue
;
1793 EFI_STRING StrValue
;
1795 Status
= EFI_SUCCESS
;
1799 // Statement don't have storage, skip them
1801 if (Question
->QuestionId
== 0) {
1806 // There are three ways to specify default value for a Question:
1807 // 1, use nested EFI_IFR_DEFAULT (highest priority)
1808 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
1809 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
1811 HiiValue
= &Question
->HiiValue
;
1814 // EFI_IFR_DEFAULT has highest priority
1816 if (!IsListEmpty (&Question
->DefaultListHead
)) {
1817 Link
= GetFirstNode (&Question
->DefaultListHead
);
1818 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
1819 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1821 if (Default
->DefaultId
== DefaultId
) {
1822 if (Default
->ValueExpression
!= NULL
) {
1824 // Default is provided by an Expression, evaluate it
1826 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
1827 if (EFI_ERROR (Status
)) {
1831 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1834 // Default value is embedded in EFI_IFR_DEFAULT
1836 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
1839 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1840 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
1841 if (StrValue
== NULL
) {
1842 return EFI_NOT_FOUND
;
1844 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
1850 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
1855 // EFI_ONE_OF_OPTION
1857 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
1858 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1860 // OneOfOption could only provide Standard and Manufacturing default
1862 Link
= GetFirstNode (&Question
->OptionListHead
);
1863 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1864 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1866 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
1867 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
1869 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1874 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1880 // EFI_IFR_CHECKBOX - lowest priority
1882 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
1883 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1885 // Checkbox could only provide Standard and Manufacturing default
1887 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
1888 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
1890 HiiValue
->Value
.b
= TRUE
;
1892 HiiValue
->Value
.b
= FALSE
;
1900 // For Questions without default
1902 switch (Question
->Operand
) {
1903 case EFI_IFR_ONE_OF_OP
:
1905 // Take first oneof option as oneof's default value
1907 if (ValueToOption (Question
, HiiValue
) == NULL
) {
1908 Link
= GetFirstNode (&Question
->OptionListHead
);
1909 if (!IsNull (&Question
->OptionListHead
, Link
)) {
1910 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1911 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1916 case EFI_IFR_ORDERED_LIST_OP
:
1918 // Take option sequence in IFR as ordered list's default value
1921 Link
= GetFirstNode (&Question
->OptionListHead
);
1922 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1923 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1925 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
1928 if (Index
>= Question
->MaxContainers
) {
1932 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1937 Status
= EFI_NOT_FOUND
;
1946 Reset Questions in a Form to their default value.
1948 @param FormSet FormSet data structure.
1949 @param Form The Form which to be reset.
1950 @param DefaultId The Class of the default.
1952 @retval EFI_SUCCESS The function completed successfully.
1956 ExtractFormDefault (
1957 IN FORM_BROWSER_FORMSET
*FormSet
,
1958 IN FORM_BROWSER_FORM
*Form
,
1964 FORM_BROWSER_STATEMENT
*Question
;
1966 Link
= GetFirstNode (&Form
->StatementListHead
);
1967 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1968 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1969 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1972 // If Question is disabled, don't reset it to default
1974 if (Question
->DisableExpression
!= NULL
) {
1975 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
1976 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
1982 // Reset Question to its default value
1984 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
1985 if (EFI_ERROR (Status
)) {
1990 // Synchronize Buffer storage's Edit buffer
1992 if ((Question
->Storage
!= NULL
) &&
1993 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1994 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2002 Initialize Question's Edit copy from Storage.
2004 @param Selection Selection contains the information about
2005 the Selection, form and formset to be displayed.
2006 Selection action may be updated in retrieve callback.
2007 @param FormSet FormSet data structure.
2008 @param Form Form data structure.
2010 @retval EFI_SUCCESS The function completed successfully.
2015 IN OUT UI_MENU_SELECTION
*Selection
,
2016 IN FORM_BROWSER_FORMSET
*FormSet
,
2017 IN FORM_BROWSER_FORM
*Form
2022 FORM_BROWSER_STATEMENT
*Question
;
2025 EFI_HII_VALUE
*HiiValue
;
2026 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2028 Link
= GetFirstNode (&Form
->StatementListHead
);
2029 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2030 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2033 // Initialize local copy of Value for each Question
2035 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2036 if (EFI_ERROR (Status
)) {
2041 // Check whether EfiVarstore with CallBack can be got.
2043 if ((Question
->QuestionId
!= 0) && (Question
->Storage
!= NULL
) &&
2044 (Question
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) &&
2045 ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
2047 // ConfigAccess can't be NULL.
2049 if (FormSet
->ConfigAccess
== NULL
) {
2050 return EFI_UNSUPPORTED
;
2053 // Check QuestionValue does exist.
2055 StorageWidth
= Question
->StorageWidth
;
2056 if (Question
->BufferValue
!= NULL
) {
2057 BufferValue
= Question
->BufferValue
;
2059 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2061 Status
= gRT
->GetVariable (
2062 Question
->VariableName
,
2063 &Question
->Storage
->Guid
,
2069 if (!EFI_ERROR (Status
)) {
2070 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2071 HiiValue
= &Question
->HiiValue
;
2072 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2073 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2075 // Create String in HII database for Configuration Driver to retrieve
2077 HiiValue
->Value
.string
= NewString ((CHAR16
*) Question
->BufferValue
, FormSet
->HiiHandle
);
2078 } else if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2079 BufferValue
= Question
->BufferValue
;
2082 Status
= FormSet
->ConfigAccess
->Callback (
2083 FormSet
->ConfigAccess
,
2084 EFI_BROWSER_ACTION_RETRIEVE
,
2085 Question
->QuestionId
,
2087 (EFI_IFR_TYPE_VALUE
*) BufferValue
,
2091 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2093 // Clean the String in HII Database
2095 DeleteString (HiiValue
->Value
.string
, FormSet
->HiiHandle
);
2098 if (!EFI_ERROR (Status
)) {
2099 switch (ActionRequest
) {
2100 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2101 gResetRequired
= TRUE
;
2104 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2106 // Till now there is no uncommitted data, so ignore this request
2110 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2111 Selection
->Action
= UI_ACTION_EXIT
;
2121 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2128 Initialize Question's Edit copy from Storage for the whole Formset.
2130 @param Selection Selection contains the information about
2131 the Selection, form and formset to be displayed.
2132 Selection action may be updated in retrieve callback.
2133 @param FormSet FormSet data structure.
2135 @retval EFI_SUCCESS The function completed successfully.
2140 IN OUT UI_MENU_SELECTION
*Selection
,
2141 IN FORM_BROWSER_FORMSET
*FormSet
2146 FORM_BROWSER_FORM
*Form
;
2148 Link
= GetFirstNode (&FormSet
->FormListHead
);
2149 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2150 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2153 // Initialize local copy of Value for each Form
2155 Status
= LoadFormConfig (Selection
, FormSet
, Form
);
2156 if (EFI_ERROR (Status
)) {
2160 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2167 Fill storage's edit copy with settings requested from Configuration Driver.
2169 @param FormSet FormSet data structure.
2170 @param Storage Buffer Storage.
2172 @retval EFI_SUCCESS The function completed successfully.
2177 IN FORM_BROWSER_FORMSET
*FormSet
,
2178 IN FORMSET_STORAGE
*Storage
2182 EFI_STRING Progress
;
2186 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2190 if (FormSet
->ConfigAccess
== NULL
) {
2191 return EFI_NOT_FOUND
;
2194 if (Storage
->ElementCount
== 0) {
2196 // Skip if there is no RequestElement
2202 // Request current settings from Configuration Driver
2204 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2205 FormSet
->ConfigAccess
,
2206 Storage
->ConfigRequest
,
2210 if (EFI_ERROR (Status
)) {
2215 // Convert Result from <ConfigAltResp> to <ConfigResp>
2217 StrPtr
= StrStr (Result
, L
"ALTCFG");
2218 if (StrPtr
!= NULL
) {
2222 Status
= ConfigRespToStorage (Storage
, Result
);
2229 Copy uncommitted data from source Storage to destination Storage.
2231 @param Dst Target Storage for uncommitted data.
2232 @param Src Source Storage for uncommitted data.
2234 @retval EFI_SUCCESS The function completed successfully.
2235 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2240 IN OUT FORMSET_STORAGE
*Dst
,
2241 IN FORMSET_STORAGE
*Src
2245 NAME_VALUE_NODE
*Node
;
2247 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2248 return EFI_INVALID_PARAMETER
;
2251 switch (Src
->Type
) {
2252 case EFI_HII_VARSTORE_BUFFER
:
2253 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
2256 case EFI_HII_VARSTORE_NAME_VALUE
:
2257 Link
= GetFirstNode (&Src
->NameValueListHead
);
2258 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
2259 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2261 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
);
2263 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
2267 case EFI_HII_VARSTORE_EFI_VARIABLE
:
2277 Get current setting of Questions.
2279 @param FormSet FormSet data structure.
2281 @retval EFI_SUCCESS The function completed successfully.
2285 InitializeCurrentSetting (
2286 IN OUT FORM_BROWSER_FORMSET
*FormSet
2291 FORMSET_STORAGE
*Storage
;
2292 FORMSET_STORAGE
*StorageSrc
;
2293 FORMSET_STORAGE
*OldStorage
;
2294 FORM_BROWSER_FORM
*Form
;
2298 // Extract default from IFR binary
2300 Link
= GetFirstNode (&FormSet
->FormListHead
);
2301 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2302 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2304 Status
= ExtractFormDefault (FormSet
, Form
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2306 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2310 // Request current settings from Configuration Driver
2312 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2313 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2314 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2317 if (gOldFormSet
!= NULL
) {
2319 // Try to find the Storage in backup formset gOldFormSet
2321 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
2322 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
2323 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
2325 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
2326 OldStorage
= StorageSrc
;
2330 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
2334 if (OldStorage
== NULL
) {
2336 // Storage is not found in backup formset, request it from ConfigDriver
2338 Status
= LoadStorage (FormSet
, Storage
);
2341 // Storage found in backup formset, use it
2343 Status
= CopyStorage (Storage
, OldStorage
);
2347 // Now Edit Buffer is filled with default values(lower priority) and current
2348 // settings(higher priority), sychronize it to shadow Buffer
2350 if (!EFI_ERROR (Status
)) {
2351 SynchronizeStorage (Storage
);
2354 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2362 Fetch the Ifr binary data of a FormSet.
2364 @param Handle PackageList Handle
2365 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2366 specified (NULL or zero GUID), take the first
2367 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2368 found in package list.
2369 On output, GUID of the formset found(if not NULL).
2370 @param BinaryLength The length of the FormSet IFR binary.
2371 @param BinaryData The buffer designed to receive the FormSet.
2373 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
2374 BufferLength was updated.
2375 @retval EFI_INVALID_PARAMETER The handle is unknown.
2376 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
2377 be found with the requested FormId.
2382 IN EFI_HII_HANDLE Handle
,
2383 IN OUT EFI_GUID
*FormSetGuid
,
2384 OUT UINTN
*BinaryLength
,
2385 OUT UINT8
**BinaryData
2389 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2395 UINT32 PackageListLength
;
2396 EFI_HII_PACKAGE_HEADER PackageHeader
;
2398 UINT8 NumberOfClassGuid
;
2399 BOOLEAN ClassGuidMatch
;
2400 EFI_GUID
*ClassGuid
;
2401 EFI_GUID
*ComparingGuid
;
2405 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2408 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
2410 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
2411 ComparingGuid
= &gEfiHiiPlatformSetupFormsetGuid
;
2413 ComparingGuid
= FormSetGuid
;
2417 // Get HII PackageList
2420 HiiPackageList
= NULL
;
2421 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2422 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2423 HiiPackageList
= AllocatePool (BufferSize
);
2424 ASSERT (HiiPackageList
!= NULL
);
2426 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2428 if (EFI_ERROR (Status
)) {
2431 ASSERT (HiiPackageList
!= NULL
);
2434 // Get Form package from this HII package List
2436 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2438 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
2440 ClassGuidMatch
= FALSE
;
2441 while (Offset
< PackageListLength
) {
2442 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
2443 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2445 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
2447 // Search FormSet in this Form Package
2449 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
2450 while (Offset2
< PackageHeader
.Length
) {
2451 OpCodeData
= Package
+ Offset2
;
2453 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
2455 // Try to compare against formset GUID
2457 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2462 // Try to compare against formset class GUID
2464 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2465 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
2466 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
2467 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
2468 ClassGuidMatch
= TRUE
;
2472 if (ClassGuidMatch
) {
2477 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
2480 if (Offset2
< PackageHeader
.Length
) {
2482 // Target formset found
2488 Offset
+= PackageHeader
.Length
;
2491 if (Offset
>= PackageListLength
) {
2493 // Form package not found in this Package List
2495 FreePool (HiiPackageList
);
2496 return EFI_NOT_FOUND
;
2499 if (ClassGuidMatch
&& (FormSetGuid
!= NULL
)) {
2501 // Return the FormSet GUID
2503 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2507 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
2508 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
2509 // of the Form Package.
2511 *BinaryLength
= PackageHeader
.Length
- Offset2
;
2512 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
2514 FreePool (HiiPackageList
);
2516 if (*BinaryData
== NULL
) {
2517 return EFI_OUT_OF_RESOURCES
;
2525 Initialize the internal data structure of a FormSet.
2527 @param Handle PackageList Handle
2528 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2529 specified (NULL or zero GUID), take the first
2530 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2531 found in package list.
2532 On output, GUID of the formset found(if not NULL).
2533 @param FormSet FormSet data structure.
2535 @retval EFI_SUCCESS The function completed successfully.
2536 @retval EFI_NOT_FOUND The specified FormSet could not be found.
2541 IN EFI_HII_HANDLE Handle
,
2542 IN OUT EFI_GUID
*FormSetGuid
,
2543 OUT FORM_BROWSER_FORMSET
*FormSet
2547 EFI_HANDLE DriverHandle
;
2550 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
2551 if (EFI_ERROR (Status
)) {
2555 FormSet
->HiiHandle
= Handle
;
2556 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
2559 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
2561 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
2562 if (EFI_ERROR (Status
)) {
2565 FormSet
->DriverHandle
= DriverHandle
;
2566 Status
= gBS
->HandleProtocol (
2568 &gEfiHiiConfigAccessProtocolGuid
,
2569 (VOID
**) &FormSet
->ConfigAccess
2571 if (EFI_ERROR (Status
)) {
2573 // Configuration Driver don't attach ConfigAccess protocol to its HII package
2574 // list, then there will be no configuration action required
2576 FormSet
->ConfigAccess
= NULL
;
2580 // Parse the IFR binary OpCodes
2582 Status
= ParseOpCodes (FormSet
);
2583 if (EFI_ERROR (Status
)) {
2587 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
2588 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2589 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
2590 gFrontPageHandle
= FormSet
->HiiHandle
;
2594 // Match GUID to find out the function key setting. If match fail, use the default setting.
2596 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
2597 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
2599 // Update the function key setting.
2601 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
2603 // Function key prompt can not be displayed if the function key has been disabled.
2605 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2606 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2609 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2610 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2620 Save globals used by previous call to SendForm(). SendForm() may be called from
2621 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
2622 So, save globals of previous call to SendForm() and restore them upon exit.
2626 SaveBrowserContext (
2630 BROWSER_CONTEXT
*Context
;
2632 gBrowserContextCount
++;
2633 if (gBrowserContextCount
== 1) {
2635 // This is not reentry of SendForm(), no context to save
2640 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
2641 ASSERT (Context
!= NULL
);
2643 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
2646 // Save FormBrowser context
2648 Context
->BannerData
= gBannerData
;
2649 Context
->ClassOfVfr
= gClassOfVfr
;
2650 Context
->FunctionKeySetting
= gFunctionKeySetting
;
2651 Context
->ResetRequired
= gResetRequired
;
2652 Context
->NvUpdateRequired
= gNvUpdateRequired
;
2653 Context
->Direction
= gDirection
;
2654 Context
->FunctionNineString
= gFunctionNineString
;
2655 Context
->FunctionTenString
= gFunctionTenString
;
2656 Context
->EnterString
= gEnterString
;
2657 Context
->EnterCommitString
= gEnterCommitString
;
2658 Context
->EnterEscapeString
= gEnterEscapeString
;
2659 Context
->EscapeString
= gEscapeString
;
2660 Context
->SaveFailed
= gSaveFailed
;
2661 Context
->MoveHighlight
= gMoveHighlight
;
2662 Context
->MakeSelection
= gMakeSelection
;
2663 Context
->DecNumericInput
= gDecNumericInput
;
2664 Context
->HexNumericInput
= gHexNumericInput
;
2665 Context
->ToggleCheckBox
= gToggleCheckBox
;
2666 Context
->PromptForData
= gPromptForData
;
2667 Context
->PromptForPassword
= gPromptForPassword
;
2668 Context
->PromptForNewPassword
= gPromptForNewPassword
;
2669 Context
->ConfirmPassword
= gConfirmPassword
;
2670 Context
->ConfirmError
= gConfirmError
;
2671 Context
->PassowordInvalid
= gPassowordInvalid
;
2672 Context
->PressEnter
= gPressEnter
;
2673 Context
->EmptyString
= gEmptyString
;
2674 Context
->AreYouSure
= gAreYouSure
;
2675 Context
->YesResponse
= gYesResponse
;
2676 Context
->NoResponse
= gNoResponse
;
2677 Context
->MiniString
= gMiniString
;
2678 Context
->PlusString
= gPlusString
;
2679 Context
->MinusString
= gMinusString
;
2680 Context
->AdjustNumber
= gAdjustNumber
;
2681 Context
->SaveChanges
= gSaveChanges
;
2682 Context
->OptionMismatch
= gOptionMismatch
;
2683 Context
->PromptBlockWidth
= gPromptBlockWidth
;
2684 Context
->OptionBlockWidth
= gOptionBlockWidth
;
2685 Context
->HelpBlockWidth
= gHelpBlockWidth
;
2686 Context
->OldFormSet
= gOldFormSet
;
2687 Context
->MenuRefreshHead
= gMenuRefreshHead
;
2689 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
2690 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
2693 // Insert to FormBrowser context list
2695 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
2700 Restore globals used by previous call to SendForm().
2704 RestoreBrowserContext (
2709 BROWSER_CONTEXT
*Context
;
2711 ASSERT (gBrowserContextCount
!= 0);
2712 gBrowserContextCount
--;
2713 if (gBrowserContextCount
== 0) {
2715 // This is not reentry of SendForm(), no context to restore
2720 ASSERT (!IsListEmpty (&gBrowserContextList
));
2722 Link
= GetFirstNode (&gBrowserContextList
);
2723 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
2726 // Restore FormBrowser context
2728 gBannerData
= Context
->BannerData
;
2729 gClassOfVfr
= Context
->ClassOfVfr
;
2730 gFunctionKeySetting
= Context
->FunctionKeySetting
;
2731 gResetRequired
= Context
->ResetRequired
;
2732 gNvUpdateRequired
= Context
->NvUpdateRequired
;
2733 gDirection
= Context
->Direction
;
2734 gFunctionNineString
= Context
->FunctionNineString
;
2735 gFunctionTenString
= Context
->FunctionTenString
;
2736 gEnterString
= Context
->EnterString
;
2737 gEnterCommitString
= Context
->EnterCommitString
;
2738 gEnterEscapeString
= Context
->EnterEscapeString
;
2739 gEscapeString
= Context
->EscapeString
;
2740 gSaveFailed
= Context
->SaveFailed
;
2741 gMoveHighlight
= Context
->MoveHighlight
;
2742 gMakeSelection
= Context
->MakeSelection
;
2743 gDecNumericInput
= Context
->DecNumericInput
;
2744 gHexNumericInput
= Context
->HexNumericInput
;
2745 gToggleCheckBox
= Context
->ToggleCheckBox
;
2746 gPromptForData
= Context
->PromptForData
;
2747 gPromptForPassword
= Context
->PromptForPassword
;
2748 gPromptForNewPassword
= Context
->PromptForNewPassword
;
2749 gConfirmPassword
= Context
->ConfirmPassword
;
2750 gConfirmError
= Context
->ConfirmError
;
2751 gPassowordInvalid
= Context
->PassowordInvalid
;
2752 gPressEnter
= Context
->PressEnter
;
2753 gEmptyString
= Context
->EmptyString
;
2754 gAreYouSure
= Context
->AreYouSure
;
2755 gYesResponse
= Context
->YesResponse
;
2756 gNoResponse
= Context
->NoResponse
;
2757 gMiniString
= Context
->MiniString
;
2758 gPlusString
= Context
->PlusString
;
2759 gMinusString
= Context
->MinusString
;
2760 gAdjustNumber
= Context
->AdjustNumber
;
2761 gSaveChanges
= Context
->SaveChanges
;
2762 gOptionMismatch
= Context
->OptionMismatch
;
2763 gPromptBlockWidth
= Context
->PromptBlockWidth
;
2764 gOptionBlockWidth
= Context
->OptionBlockWidth
;
2765 gHelpBlockWidth
= Context
->HelpBlockWidth
;
2766 gOldFormSet
= Context
->OldFormSet
;
2767 gMenuRefreshHead
= Context
->MenuRefreshHead
;
2769 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
2770 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
2773 // Remove from FormBrowser context list
2775 RemoveEntryList (&Context
->Link
);
2776 gBS
->FreePool (Context
);