2 Entry and initialization module for the browser.
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5 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
= (CHAR16
) (gOptionBlockWidth
+ LEFT_SKIPPED_COLUMNS
);
273 gOptionBlockWidth
= (CHAR16
) (gOptionBlockWidth
- LEFT_SKIPPED_COLUMNS
);
276 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
278 InitializeBrowserStrings ();
280 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
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 if (HiiHandle
== NULL
) {
669 String
= HiiGetString (HiiHandle
, Token
, NULL
);
670 if (String
== NULL
) {
671 String
= AllocateCopyPool (sizeof (mUnknownString
), mUnknownString
);
672 ASSERT (String
!= NULL
);
674 return (CHAR16
*) String
;
679 Allocate new memory and then copy the Unicode string Source to Destination.
681 @param Dest Location to copy string
682 @param Src String to copy
687 IN OUT CHAR16
**Dest
,
694 *Dest
= AllocateCopyPool (StrSize (Src
), Src
);
695 ASSERT (*Dest
!= NULL
);
700 Allocate new memory and concatinate Source on the end of Destination.
702 @param Dest String to added to the end of.
703 @param Src String to concatinate.
708 IN OUT CHAR16
**Dest
,
716 NewStringCpy (Dest
, Src
);
720 TmpSize
= StrSize (*Dest
);
721 NewString
= AllocateZeroPool (TmpSize
+ StrSize (Src
) - 1);
722 ASSERT (NewString
!= NULL
);
724 StrCpy (NewString
, *Dest
);
725 StrCat (NewString
, Src
);
733 Synchronize Storage's Edit copy to Shadow copy.
735 @param Storage The Storage to be synchronized.
740 IN FORMSET_STORAGE
*Storage
744 NAME_VALUE_NODE
*Node
;
746 switch (Storage
->Type
) {
747 case EFI_HII_VARSTORE_BUFFER
:
748 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
751 case EFI_HII_VARSTORE_NAME_VALUE
:
752 Link
= GetFirstNode (&Storage
->NameValueListHead
);
753 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
754 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
756 NewStringCpy (&Node
->Value
, Node
->EditValue
);
758 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
762 case EFI_HII_VARSTORE_EFI_VARIABLE
:
770 Get Value for given Name from a NameValue Storage.
772 @param Storage The NameValue Storage.
773 @param Name The Name.
774 @param Value The retured Value.
776 @retval EFI_SUCCESS Value found for given Name.
777 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
782 IN FORMSET_STORAGE
*Storage
,
784 IN OUT CHAR16
**Value
788 NAME_VALUE_NODE
*Node
;
792 Link
= GetFirstNode (&Storage
->NameValueListHead
);
793 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
794 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
796 if (StrCmp (Name
, Node
->Name
) == 0) {
797 NewStringCpy (Value
, Node
->EditValue
);
801 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
804 return EFI_NOT_FOUND
;
809 Set Value of given Name in a NameValue Storage.
811 @param Storage The NameValue Storage.
812 @param Name The Name.
813 @param Value The Value to set.
815 @retval EFI_SUCCESS Value found for given Name.
816 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
821 IN FORMSET_STORAGE
*Storage
,
827 NAME_VALUE_NODE
*Node
;
829 Link
= GetFirstNode (&Storage
->NameValueListHead
);
830 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
831 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
833 if (StrCmp (Name
, Node
->Name
) == 0) {
834 if (Node
->EditValue
!= NULL
) {
835 FreePool (Node
->EditValue
);
837 Node
->EditValue
= AllocateCopyPool (StrSize (Value
), Value
);
838 ASSERT (Node
->EditValue
!= NULL
);
842 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
845 return EFI_NOT_FOUND
;
850 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
852 @param Storage The Storage to be conveted.
853 @param ConfigResp The returned <ConfigResp>.
855 @retval EFI_SUCCESS Convert success.
856 @retval EFI_INVALID_PARAMETER Incorrect storage type.
860 StorageToConfigResp (
861 IN FORMSET_STORAGE
*Storage
,
862 IN CHAR16
**ConfigResp
868 NAME_VALUE_NODE
*Node
;
870 Status
= EFI_SUCCESS
;
872 switch (Storage
->Type
) {
873 case EFI_HII_VARSTORE_BUFFER
:
874 Status
= mHiiConfigRouting
->BlockToConfig (
876 Storage
->ConfigRequest
,
884 case EFI_HII_VARSTORE_NAME_VALUE
:
886 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
888 Link
= GetFirstNode (&Storage
->NameValueListHead
);
889 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
890 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
892 NewStringCat (ConfigResp
, L
"&");
893 NewStringCat (ConfigResp
, Node
->Name
);
894 NewStringCat (ConfigResp
, L
"=");
895 NewStringCat (ConfigResp
, Node
->EditValue
);
897 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
901 case EFI_HII_VARSTORE_EFI_VARIABLE
:
903 Status
= EFI_INVALID_PARAMETER
;
912 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
914 @param Storage The Storage to receive the settings.
915 @param ConfigResp The <ConfigResp> to be converted.
917 @retval EFI_SUCCESS Convert success.
918 @retval EFI_INVALID_PARAMETER Incorrect storage type.
922 ConfigRespToStorage (
923 IN FORMSET_STORAGE
*Storage
,
924 IN CHAR16
*ConfigResp
934 Status
= EFI_SUCCESS
;
936 switch (Storage
->Type
) {
937 case EFI_HII_VARSTORE_BUFFER
:
938 BufferSize
= Storage
->Size
;
939 Status
= mHiiConfigRouting
->ConfigToBlock (
948 case EFI_HII_VARSTORE_NAME_VALUE
:
949 StrPtr
= StrStr (ConfigResp
, L
"PATH");
950 if (StrPtr
== NULL
) {
953 StrPtr
= StrStr (ConfigResp
, L
"&");
954 while (StrPtr
!= NULL
) {
960 StrPtr
= StrStr (StrPtr
, L
"=");
961 if (StrPtr
== NULL
) {
971 StrPtr
= StrStr (StrPtr
, L
"&");
972 if (StrPtr
!= NULL
) {
975 SetValueByName (Storage
, Name
, Value
);
979 case EFI_HII_VARSTORE_EFI_VARIABLE
:
981 Status
= EFI_INVALID_PARAMETER
;
990 Get Question's current Value.
992 @param FormSet FormSet data structure.
993 @param Form Form data structure.
994 @param Question Question to be initialized.
995 @param Cached TRUE: get from Edit copy FALSE: get from original
998 @retval EFI_SUCCESS The function completed successfully.
1003 IN FORM_BROWSER_FORMSET
*FormSet
,
1004 IN FORM_BROWSER_FORM
*Form
,
1005 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1015 FORMSET_STORAGE
*Storage
;
1016 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1017 CHAR16
*ConfigRequest
;
1025 BOOLEAN IsBufferStorage
;
1030 Status
= EFI_SUCCESS
;
1033 // Statement don't have storage, skip them
1035 if (Question
->QuestionId
== 0) {
1040 // Question value is provided by an Expression, evaluate it
1042 if (Question
->ValueExpression
!= NULL
) {
1043 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1044 if (!EFI_ERROR (Status
)) {
1045 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1051 // Get question value by read expression.
1053 if (Question
->ReadExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1054 Status
= EvaluateExpression (FormSet
, Form
, Question
->ReadExpression
);
1055 if (!EFI_ERROR (Status
) && (Question
->ReadExpression
->Result
.Type
< EFI_IFR_TYPE_OTHER
)) {
1057 // Only update question value to the valid result.
1059 CopyMem (&Question
->HiiValue
, &Question
->ReadExpression
->Result
, sizeof (EFI_HII_VALUE
));
1065 // Question value is provided by RTC
1067 Storage
= Question
->Storage
;
1068 QuestionValue
= &Question
->HiiValue
.Value
;
1069 if (Storage
== NULL
) {
1071 // It's a Question without storage, or RTC date/time
1073 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1075 // Date and time define the same Flags bit
1077 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1078 case QF_DATE_STORAGE_TIME
:
1079 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1082 case QF_DATE_STORAGE_WAKEUP
:
1083 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1086 case QF_DATE_STORAGE_NORMAL
:
1089 // For date/time without storage
1094 if (EFI_ERROR (Status
)) {
1098 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1099 QuestionValue
->date
.Year
= EfiTime
.Year
;
1100 QuestionValue
->date
.Month
= EfiTime
.Month
;
1101 QuestionValue
->date
.Day
= EfiTime
.Day
;
1103 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1104 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1105 QuestionValue
->time
.Second
= EfiTime
.Second
;
1113 // Question value is provided by EFI variable
1115 StorageWidth
= Question
->StorageWidth
;
1116 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1117 if (Question
->BufferValue
!= NULL
) {
1118 Dst
= Question
->BufferValue
;
1120 Dst
= (UINT8
*) QuestionValue
;
1123 Status
= gRT
->GetVariable (
1124 Question
->VariableName
,
1131 // Always return success, even this EFI variable doesn't exist
1137 // Question Value is provided by Buffer Storage or NameValue Storage
1139 if (Question
->BufferValue
!= NULL
) {
1141 // This Question is password or orderedlist
1143 Dst
= Question
->BufferValue
;
1146 // Other type of Questions
1148 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1151 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1152 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1154 if (IsBufferStorage
) {
1156 // Copy from storage Edit buffer
1158 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1161 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1162 if (EFI_ERROR (Status
)) {
1166 ASSERT (Value
!= NULL
);
1167 LengthStr
= StrLen (Value
);
1168 Status
= EFI_SUCCESS
;
1171 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1172 // Add string tail char L'\0' into Length
1174 Length
= StorageWidth
+ sizeof (CHAR16
);
1175 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1176 Status
= EFI_BUFFER_TOO_SMALL
;
1178 StringPtr
= (CHAR16
*) Dst
;
1179 ZeroMem (TemStr
, sizeof (TemStr
));
1180 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1181 StrnCpy (TemStr
, Value
+ Index
, 4);
1182 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1185 // Add tailing L'\0' character
1187 StringPtr
[Index
/4] = L
'\0';
1190 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1191 Status
= EFI_BUFFER_TOO_SMALL
;
1193 ZeroMem (TemStr
, sizeof (TemStr
));
1194 for (Index
= 0; Index
< LengthStr
; Index
++) {
1195 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1196 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1197 if ((Index
& 1) == 0) {
1198 Dst
[Index
/2] = DigitUint8
;
1200 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1210 // Request current settings from Configuration Driver
1212 if (FormSet
->ConfigAccess
== NULL
) {
1213 return EFI_NOT_FOUND
;
1217 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1218 // <ConfigHdr> + "&" + <VariableName>
1220 if (IsBufferStorage
) {
1221 Length
= StrLen (Storage
->ConfigHdr
);
1222 Length
+= StrLen (Question
->BlockName
);
1224 Length
= StrLen (Storage
->ConfigHdr
);
1225 Length
+= StrLen (Question
->VariableName
) + 1;
1227 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1228 ASSERT (ConfigRequest
!= NULL
);
1230 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1231 if (IsBufferStorage
) {
1232 StrCat (ConfigRequest
, Question
->BlockName
);
1234 StrCat (ConfigRequest
, L
"&");
1235 StrCat (ConfigRequest
, Question
->VariableName
);
1238 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1239 FormSet
->ConfigAccess
,
1244 if (EFI_ERROR (Status
)) {
1249 // Skip <ConfigRequest>
1251 Value
= Result
+ Length
;
1252 if (IsBufferStorage
) {
1258 if (*Value
!= '=') {
1260 return EFI_NOT_FOUND
;
1263 // Skip '=', point to value
1268 // Suppress <AltResp> if any
1271 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1276 LengthStr
= StrLen (Value
);
1277 Status
= EFI_SUCCESS
;
1278 if (!IsBufferStorage
&& IsString
) {
1280 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1281 // Add string tail char L'\0' into Length
1283 Length
= StorageWidth
+ sizeof (CHAR16
);
1284 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1285 Status
= EFI_BUFFER_TOO_SMALL
;
1287 StringPtr
= (CHAR16
*) Dst
;
1288 ZeroMem (TemStr
, sizeof (TemStr
));
1289 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1290 StrnCpy (TemStr
, Value
+ Index
, 4);
1291 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1294 // Add tailing L'\0' character
1296 StringPtr
[Index
/4] = L
'\0';
1299 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1300 Status
= EFI_BUFFER_TOO_SMALL
;
1302 ZeroMem (TemStr
, sizeof (TemStr
));
1303 for (Index
= 0; Index
< LengthStr
; Index
++) {
1304 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1305 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1306 if ((Index
& 1) == 0) {
1307 Dst
[Index
/2] = DigitUint8
;
1309 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1315 if (EFI_ERROR (Status
)) {
1321 // Synchronize Edit Buffer
1323 if (IsBufferStorage
) {
1324 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1326 SetValueByName (Storage
, Question
->VariableName
, Value
);
1337 Save Question Value to edit copy(cached) or Storage(uncached).
1339 @param FormSet FormSet data structure.
1340 @param Form Form data structure.
1341 @param Question Pointer to the Question.
1342 @param Cached TRUE: set to Edit copy FALSE: set to original
1345 @retval EFI_SUCCESS The function completed successfully.
1350 IN FORM_BROWSER_FORMSET
*FormSet
,
1351 IN FORM_BROWSER_FORM
*Form
,
1352 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1363 FORMSET_STORAGE
*Storage
;
1364 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1369 BOOLEAN IsBufferStorage
;
1376 Status
= EFI_SUCCESS
;
1379 // Statement don't have storage, skip them
1381 if (Question
->QuestionId
== 0) {
1386 // If Question value is provided by an Expression, then it is read only
1388 if (Question
->ValueExpression
!= NULL
) {
1393 // Before set question value, evaluate its write expression.
1395 if (Question
->WriteExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1396 Status
= EvaluateExpression (FormSet
, Form
, Question
->WriteExpression
);
1397 if (EFI_ERROR (Status
)) {
1403 // Question value is provided by RTC
1405 Storage
= Question
->Storage
;
1406 QuestionValue
= &Question
->HiiValue
.Value
;
1407 if (Storage
== NULL
) {
1409 // It's a Question without storage, or RTC date/time
1411 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1413 // Date and time define the same Flags bit
1415 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1416 case QF_DATE_STORAGE_TIME
:
1417 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1420 case QF_DATE_STORAGE_WAKEUP
:
1421 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1424 case QF_DATE_STORAGE_NORMAL
:
1427 // For date/time without storage
1432 if (EFI_ERROR (Status
)) {
1436 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1437 EfiTime
.Year
= QuestionValue
->date
.Year
;
1438 EfiTime
.Month
= QuestionValue
->date
.Month
;
1439 EfiTime
.Day
= QuestionValue
->date
.Day
;
1441 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1442 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1443 EfiTime
.Second
= QuestionValue
->time
.Second
;
1446 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1447 Status
= gRT
->SetTime (&EfiTime
);
1449 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1457 // Question value is provided by EFI variable
1459 StorageWidth
= Question
->StorageWidth
;
1460 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1461 if (Question
->BufferValue
!= NULL
) {
1462 Src
= Question
->BufferValue
;
1464 Src
= (UINT8
*) QuestionValue
;
1467 Status
= gRT
->SetVariable (
1468 Question
->VariableName
,
1470 Storage
->Attributes
,
1478 // Question Value is provided by Buffer Storage or NameValue Storage
1480 if (Question
->BufferValue
!= NULL
) {
1481 Src
= Question
->BufferValue
;
1483 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1486 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1487 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1488 if (IsBufferStorage
) {
1490 // Copy to storage edit buffer
1492 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1496 // Allocate enough string buffer.
1499 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1500 Value
= AllocateZeroPool (BufferLen
);
1501 ASSERT (Value
!= NULL
);
1503 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1505 TemName
= (CHAR16
*) Src
;
1507 for (; *TemName
!= L
'\0'; TemName
++) {
1508 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1511 BufferLen
= StorageWidth
* 2 + 1;
1512 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1513 ASSERT (Value
!= NULL
);
1515 // Convert Buffer to Hex String
1517 TemBuffer
= Src
+ StorageWidth
- 1;
1519 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1520 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1524 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
);
1530 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1531 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1533 if (IsBufferStorage
) {
1534 Length
= StrLen (Question
->BlockName
) + 7;
1536 Length
= StrLen (Question
->VariableName
) + 2;
1538 if (!IsBufferStorage
&& IsString
) {
1539 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1541 Length
+= (StorageWidth
* 2);
1543 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1544 ASSERT (ConfigResp
!= NULL
);
1546 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1547 if (IsBufferStorage
) {
1548 StrCat (ConfigResp
, Question
->BlockName
);
1549 StrCat (ConfigResp
, L
"&VALUE=");
1551 StrCat (ConfigResp
, L
"&");
1552 StrCat (ConfigResp
, Question
->VariableName
);
1553 StrCat (ConfigResp
, L
"=");
1556 Value
= ConfigResp
+ StrLen (ConfigResp
);
1558 if (!IsBufferStorage
&& IsString
) {
1560 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1562 TemName
= (CHAR16
*) Src
;
1564 for (; *TemName
!= L
'\0'; TemName
++) {
1565 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1569 // Convert Buffer to Hex String
1571 TemBuffer
= Src
+ StorageWidth
- 1;
1573 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1574 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1579 // Convert to lower char.
1581 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1582 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1583 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1588 // Submit Question Value to Configuration Driver
1590 if (FormSet
->ConfigAccess
!= NULL
) {
1591 Status
= FormSet
->ConfigAccess
->RouteConfig (
1592 FormSet
->ConfigAccess
,
1596 if (EFI_ERROR (Status
)) {
1597 FreePool (ConfigResp
);
1601 FreePool (ConfigResp
);
1604 // Synchronize shadow Buffer
1606 SynchronizeStorage (Storage
);
1614 Perform inconsistent check for a Form.
1616 @param FormSet FormSet data structure.
1617 @param Form Form data structure.
1618 @param Question The Question to be validated.
1619 @param Type Validation type: InConsistent or NoSubmit
1621 @retval EFI_SUCCESS Form validation pass.
1622 @retval other Form validation failed.
1627 IN FORM_BROWSER_FORMSET
*FormSet
,
1628 IN FORM_BROWSER_FORM
*Form
,
1629 IN FORM_BROWSER_STATEMENT
*Question
,
1635 LIST_ENTRY
*ListHead
;
1638 FORM_EXPRESSION
*Expression
;
1640 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1641 ListHead
= &Question
->InconsistentListHead
;
1642 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1643 ListHead
= &Question
->NoSubmitListHead
;
1645 return EFI_UNSUPPORTED
;
1648 Link
= GetFirstNode (ListHead
);
1649 while (!IsNull (ListHead
, Link
)) {
1650 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1653 // Evaluate the expression
1655 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1656 if (EFI_ERROR (Status
)) {
1660 if (Expression
->Result
.Value
.b
) {
1662 // Condition meet, show up error message
1664 if (Expression
->Error
!= 0) {
1665 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1667 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1668 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1672 return EFI_NOT_READY
;
1675 Link
= GetNextNode (ListHead
, Link
);
1683 Perform NoSubmit check for each Form in FormSet.
1685 @param FormSet FormSet data structure.
1687 @retval EFI_SUCCESS Form validation pass.
1688 @retval other Form validation failed.
1693 IN FORM_BROWSER_FORMSET
*FormSet
1698 FORM_BROWSER_STATEMENT
*Question
;
1699 FORM_BROWSER_FORM
*Form
;
1700 LIST_ENTRY
*LinkForm
;
1702 LinkForm
= GetFirstNode (&FormSet
->FormListHead
);
1703 while (!IsNull (&FormSet
->FormListHead
, LinkForm
)) {
1704 Form
= FORM_BROWSER_FORM_FROM_LINK (LinkForm
);
1706 Link
= GetFirstNode (&Form
->StatementListHead
);
1707 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1708 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1710 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1711 if (EFI_ERROR (Status
)) {
1715 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1718 LinkForm
= GetNextNode (&FormSet
->FormListHead
, LinkForm
);
1728 @param FormSet FormSet data structure.
1729 @param Form Form data structure.
1731 @retval EFI_SUCCESS The function completed successfully.
1736 IN FORM_BROWSER_FORMSET
*FormSet
,
1737 IN FORM_BROWSER_FORM
*Form
1742 EFI_STRING ConfigResp
;
1743 EFI_STRING Progress
;
1744 FORMSET_STORAGE
*Storage
;
1747 // Validate the Form by NoSubmit check
1749 Status
= NoSubmitCheck (FormSet
);
1750 if (EFI_ERROR (Status
)) {
1755 // Submit Buffer storage or Name/Value storage
1757 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1758 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1759 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1760 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1762 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1767 // Skip if there is no RequestElement
1769 if (Storage
->ElementCount
== 0) {
1774 // Prepare <ConfigResp>
1776 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
1777 if (EFI_ERROR (Status
)) {
1782 // Send <ConfigResp> to Configuration Driver
1784 if (FormSet
->ConfigAccess
!= NULL
) {
1785 Status
= FormSet
->ConfigAccess
->RouteConfig (
1786 FormSet
->ConfigAccess
,
1790 if (EFI_ERROR (Status
)) {
1791 FreePool (ConfigResp
);
1795 FreePool (ConfigResp
);
1798 // Config success, update storage shadow Buffer
1800 SynchronizeStorage (Storage
);
1803 gNvUpdateRequired
= FALSE
;
1810 Reset Question to its default value.
1812 @param FormSet The form set.
1813 @param Form The form.
1814 @param Question The question.
1815 @param DefaultId The Class of the default.
1817 @retval EFI_SUCCESS Question is reset to default value.
1821 GetQuestionDefault (
1822 IN FORM_BROWSER_FORMSET
*FormSet
,
1823 IN FORM_BROWSER_FORM
*Form
,
1824 IN FORM_BROWSER_STATEMENT
*Question
,
1830 QUESTION_DEFAULT
*Default
;
1831 QUESTION_OPTION
*Option
;
1832 EFI_HII_VALUE
*HiiValue
;
1834 EFI_STRING StrValue
;
1836 Status
= EFI_SUCCESS
;
1840 // Statement don't have storage, skip them
1842 if (Question
->QuestionId
== 0) {
1847 // There are three ways to specify default value for a Question:
1848 // 1, use nested EFI_IFR_DEFAULT (highest priority)
1849 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
1850 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
1852 HiiValue
= &Question
->HiiValue
;
1855 // EFI_IFR_DEFAULT has highest priority
1857 if (!IsListEmpty (&Question
->DefaultListHead
)) {
1858 Link
= GetFirstNode (&Question
->DefaultListHead
);
1859 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
1860 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1862 if (Default
->DefaultId
== DefaultId
) {
1863 if (Default
->ValueExpression
!= NULL
) {
1865 // Default is provided by an Expression, evaluate it
1867 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
1868 if (EFI_ERROR (Status
)) {
1872 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1875 // Default value is embedded in EFI_IFR_DEFAULT
1877 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
1880 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1881 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
1882 if (StrValue
== NULL
) {
1883 return EFI_NOT_FOUND
;
1885 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
1891 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
1896 // EFI_ONE_OF_OPTION
1898 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
1899 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1901 // OneOfOption could only provide Standard and Manufacturing default
1903 Link
= GetFirstNode (&Question
->OptionListHead
);
1904 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1905 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1907 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
1908 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
1910 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1915 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1921 // EFI_IFR_CHECKBOX - lowest priority
1923 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
1924 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1926 // Checkbox could only provide Standard and Manufacturing default
1928 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
1929 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
1931 HiiValue
->Value
.b
= TRUE
;
1933 HiiValue
->Value
.b
= FALSE
;
1941 // For Questions without default
1943 switch (Question
->Operand
) {
1944 case EFI_IFR_ONE_OF_OP
:
1946 // Take first oneof option as oneof's default value
1948 if (ValueToOption (Question
, HiiValue
) == NULL
) {
1949 Link
= GetFirstNode (&Question
->OptionListHead
);
1950 if (!IsNull (&Question
->OptionListHead
, Link
)) {
1951 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1952 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1957 case EFI_IFR_ORDERED_LIST_OP
:
1959 // Take option sequence in IFR as ordered list's default value
1962 Link
= GetFirstNode (&Question
->OptionListHead
);
1963 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1964 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1966 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
1969 if (Index
>= Question
->MaxContainers
) {
1973 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1978 Status
= EFI_NOT_FOUND
;
1987 Reset Questions in a Form to their default value.
1989 @param FormSet FormSet data structure.
1990 @param Form The Form which to be reset.
1991 @param DefaultId The Class of the default.
1993 @retval EFI_SUCCESS The function completed successfully.
1997 ExtractFormDefault (
1998 IN FORM_BROWSER_FORMSET
*FormSet
,
1999 IN FORM_BROWSER_FORM
*Form
,
2005 FORM_BROWSER_STATEMENT
*Question
;
2007 Link
= GetFirstNode (&Form
->StatementListHead
);
2008 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2009 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2010 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2013 // If Question is disabled, don't reset it to default
2015 if (Question
->DisableExpression
!= NULL
) {
2016 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
2017 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
2023 // Reset Question to its default value
2025 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
2026 if (EFI_ERROR (Status
)) {
2031 // Synchronize Buffer storage's Edit buffer
2033 if ((Question
->Storage
!= NULL
) &&
2034 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
2035 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2043 Initialize Question's Edit copy from Storage.
2045 @param Selection Selection contains the information about
2046 the Selection, form and formset to be displayed.
2047 Selection action may be updated in retrieve callback.
2048 @param FormSet FormSet data structure.
2049 @param Form Form data structure.
2051 @retval EFI_SUCCESS The function completed successfully.
2056 IN OUT UI_MENU_SELECTION
*Selection
,
2057 IN FORM_BROWSER_FORMSET
*FormSet
,
2058 IN FORM_BROWSER_FORM
*Form
2063 FORM_BROWSER_STATEMENT
*Question
;
2066 EFI_HII_VALUE
*HiiValue
;
2067 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2069 Link
= GetFirstNode (&Form
->StatementListHead
);
2070 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2071 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2074 // Initialize local copy of Value for each Question
2076 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2077 if (EFI_ERROR (Status
)) {
2082 // Check whether EfiVarstore with CallBack can be got.
2084 if ((FormSet
->ConfigAccess
!= NULL
) &&
2085 (Selection
->Action
!= UI_ACTION_REFRESH_FORMSET
) &&
2086 (Question
->QuestionId
!= 0) &&
2087 (Question
->Storage
!= NULL
) &&
2088 (Question
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) &&
2089 ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
2092 // Check QuestionValue does exist.
2094 StorageWidth
= Question
->StorageWidth
;
2095 if (Question
->BufferValue
!= NULL
) {
2096 BufferValue
= Question
->BufferValue
;
2098 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2100 Status
= gRT
->GetVariable (
2101 Question
->VariableName
,
2102 &Question
->Storage
->Guid
,
2108 if (!EFI_ERROR (Status
)) {
2109 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2110 HiiValue
= &Question
->HiiValue
;
2111 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2112 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2114 // Create String in HII database for Configuration Driver to retrieve
2116 HiiValue
->Value
.string
= NewString ((CHAR16
*) Question
->BufferValue
, FormSet
->HiiHandle
);
2117 } else if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2118 BufferValue
= Question
->BufferValue
;
2121 Status
= FormSet
->ConfigAccess
->Callback (
2122 FormSet
->ConfigAccess
,
2123 EFI_BROWSER_ACTION_RETRIEVE
,
2124 Question
->QuestionId
,
2126 (EFI_IFR_TYPE_VALUE
*) BufferValue
,
2130 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2132 // Clean the String in HII Database
2134 DeleteString (HiiValue
->Value
.string
, FormSet
->HiiHandle
);
2137 if (!EFI_ERROR (Status
)) {
2138 switch (ActionRequest
) {
2139 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2140 gResetRequired
= TRUE
;
2143 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2145 // Till now there is no uncommitted data, so ignore this request
2149 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2150 Selection
->Action
= UI_ACTION_EXIT
;
2160 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2167 Initialize Question's Edit copy from Storage for the whole Formset.
2169 @param Selection Selection contains the information about
2170 the Selection, form and formset to be displayed.
2171 Selection action may be updated in retrieve callback.
2172 @param FormSet FormSet data structure.
2174 @retval EFI_SUCCESS The function completed successfully.
2179 IN OUT UI_MENU_SELECTION
*Selection
,
2180 IN FORM_BROWSER_FORMSET
*FormSet
2185 FORM_BROWSER_FORM
*Form
;
2187 Link
= GetFirstNode (&FormSet
->FormListHead
);
2188 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2189 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2192 // Initialize local copy of Value for each Form
2194 Status
= LoadFormConfig (Selection
, FormSet
, Form
);
2195 if (EFI_ERROR (Status
)) {
2199 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2206 Fill storage's edit copy with settings requested from Configuration Driver.
2208 @param FormSet FormSet data structure.
2209 @param Storage Buffer Storage.
2211 @retval EFI_SUCCESS The function completed successfully.
2216 IN FORM_BROWSER_FORMSET
*FormSet
,
2217 IN FORMSET_STORAGE
*Storage
2221 EFI_STRING Progress
;
2225 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2229 if (FormSet
->ConfigAccess
== NULL
) {
2230 return EFI_NOT_FOUND
;
2233 if (Storage
->ElementCount
== 0) {
2235 // Skip if there is no RequestElement
2241 // Request current settings from Configuration Driver
2243 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2244 FormSet
->ConfigAccess
,
2245 Storage
->ConfigRequest
,
2249 if (EFI_ERROR (Status
)) {
2254 // Convert Result from <ConfigAltResp> to <ConfigResp>
2256 StrPtr
= StrStr (Result
, L
"ALTCFG");
2257 if (StrPtr
!= NULL
) {
2261 Status
= ConfigRespToStorage (Storage
, Result
);
2268 Copy uncommitted data from source Storage to destination Storage.
2270 @param Dst Target Storage for uncommitted data.
2271 @param Src Source Storage for uncommitted data.
2273 @retval EFI_SUCCESS The function completed successfully.
2274 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2279 IN OUT FORMSET_STORAGE
*Dst
,
2280 IN FORMSET_STORAGE
*Src
2284 NAME_VALUE_NODE
*Node
;
2286 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2287 return EFI_INVALID_PARAMETER
;
2290 switch (Src
->Type
) {
2291 case EFI_HII_VARSTORE_BUFFER
:
2292 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
2295 case EFI_HII_VARSTORE_NAME_VALUE
:
2296 Link
= GetFirstNode (&Src
->NameValueListHead
);
2297 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
2298 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2300 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
);
2302 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
2306 case EFI_HII_VARSTORE_EFI_VARIABLE
:
2316 Get current setting of Questions.
2318 @param FormSet FormSet data structure.
2320 @retval EFI_SUCCESS The function completed successfully.
2324 InitializeCurrentSetting (
2325 IN OUT FORM_BROWSER_FORMSET
*FormSet
2330 FORMSET_STORAGE
*Storage
;
2331 FORMSET_STORAGE
*StorageSrc
;
2332 FORMSET_STORAGE
*OldStorage
;
2333 FORM_BROWSER_FORM
*Form
;
2337 // Extract default from IFR binary
2339 Link
= GetFirstNode (&FormSet
->FormListHead
);
2340 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2341 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2343 Status
= ExtractFormDefault (FormSet
, Form
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2345 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2349 // Request current settings from Configuration Driver
2351 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2352 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2353 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2356 if (gOldFormSet
!= NULL
) {
2358 // Try to find the Storage in backup formset gOldFormSet
2360 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
2361 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
2362 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
2364 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
2365 OldStorage
= StorageSrc
;
2369 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
2373 if (OldStorage
== NULL
) {
2375 // Storage is not found in backup formset, request it from ConfigDriver
2377 Status
= LoadStorage (FormSet
, Storage
);
2380 // Storage found in backup formset, use it
2382 Status
= CopyStorage (Storage
, OldStorage
);
2386 // Now Edit Buffer is filled with default values(lower priority) and current
2387 // settings(higher priority), sychronize it to shadow Buffer
2389 if (!EFI_ERROR (Status
)) {
2390 SynchronizeStorage (Storage
);
2393 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2401 Fetch the Ifr binary data of a FormSet.
2403 @param Handle PackageList Handle
2404 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2405 specified (NULL or zero GUID), take the first
2406 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2407 found in package list.
2408 On output, GUID of the formset found(if not NULL).
2409 @param BinaryLength The length of the FormSet IFR binary.
2410 @param BinaryData The buffer designed to receive the FormSet.
2412 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
2413 BufferLength was updated.
2414 @retval EFI_INVALID_PARAMETER The handle is unknown.
2415 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
2416 be found with the requested FormId.
2421 IN EFI_HII_HANDLE Handle
,
2422 IN OUT EFI_GUID
*FormSetGuid
,
2423 OUT UINTN
*BinaryLength
,
2424 OUT UINT8
**BinaryData
2428 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2434 UINT32 PackageListLength
;
2435 EFI_HII_PACKAGE_HEADER PackageHeader
;
2437 UINT8 NumberOfClassGuid
;
2438 BOOLEAN ClassGuidMatch
;
2439 EFI_GUID
*ClassGuid
;
2440 EFI_GUID
*ComparingGuid
;
2444 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2447 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
2449 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
2450 ComparingGuid
= &gEfiHiiPlatformSetupFormsetGuid
;
2452 ComparingGuid
= FormSetGuid
;
2456 // Get HII PackageList
2459 HiiPackageList
= NULL
;
2460 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2461 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2462 HiiPackageList
= AllocatePool (BufferSize
);
2463 ASSERT (HiiPackageList
!= NULL
);
2465 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2467 if (EFI_ERROR (Status
)) {
2470 ASSERT (HiiPackageList
!= NULL
);
2473 // Get Form package from this HII package List
2475 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2477 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
2479 ClassGuidMatch
= FALSE
;
2480 while (Offset
< PackageListLength
) {
2481 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
2482 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2484 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
2486 // Search FormSet in this Form Package
2488 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
2489 while (Offset2
< PackageHeader
.Length
) {
2490 OpCodeData
= Package
+ Offset2
;
2492 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
2494 // Try to compare against formset GUID
2496 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2500 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
2502 // Try to compare against formset class GUID
2504 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2505 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
2506 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
2507 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
2508 ClassGuidMatch
= TRUE
;
2512 if (ClassGuidMatch
) {
2515 } else if (ComparingGuid
== &gEfiHiiPlatformSetupFormsetGuid
) {
2516 ClassGuidMatch
= TRUE
;
2521 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
2524 if (Offset2
< PackageHeader
.Length
) {
2526 // Target formset found
2532 Offset
+= PackageHeader
.Length
;
2535 if (Offset
>= PackageListLength
) {
2537 // Form package not found in this Package List
2539 FreePool (HiiPackageList
);
2540 return EFI_NOT_FOUND
;
2543 if (ClassGuidMatch
&& (FormSetGuid
!= NULL
)) {
2545 // Return the FormSet GUID
2547 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2551 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
2552 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
2553 // of the Form Package.
2555 *BinaryLength
= PackageHeader
.Length
- Offset2
;
2556 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
2558 FreePool (HiiPackageList
);
2560 if (*BinaryData
== NULL
) {
2561 return EFI_OUT_OF_RESOURCES
;
2569 Initialize the internal data structure of a FormSet.
2571 @param Handle PackageList Handle
2572 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2573 specified (NULL or zero GUID), take the first
2574 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2575 found in package list.
2576 On output, GUID of the formset found(if not NULL).
2577 @param FormSet FormSet data structure.
2579 @retval EFI_SUCCESS The function completed successfully.
2580 @retval EFI_NOT_FOUND The specified FormSet could not be found.
2585 IN EFI_HII_HANDLE Handle
,
2586 IN OUT EFI_GUID
*FormSetGuid
,
2587 OUT FORM_BROWSER_FORMSET
*FormSet
2591 EFI_HANDLE DriverHandle
;
2594 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
2595 if (EFI_ERROR (Status
)) {
2599 FormSet
->HiiHandle
= Handle
;
2600 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
2603 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
2605 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
2606 if (EFI_ERROR (Status
)) {
2609 FormSet
->DriverHandle
= DriverHandle
;
2610 Status
= gBS
->HandleProtocol (
2612 &gEfiHiiConfigAccessProtocolGuid
,
2613 (VOID
**) &FormSet
->ConfigAccess
2615 if (EFI_ERROR (Status
)) {
2617 // Configuration Driver don't attach ConfigAccess protocol to its HII package
2618 // list, then there will be no configuration action required
2620 FormSet
->ConfigAccess
= NULL
;
2624 // Parse the IFR binary OpCodes
2626 Status
= ParseOpCodes (FormSet
);
2627 if (EFI_ERROR (Status
)) {
2632 // Set VFR type by FormSet SubClass field
2634 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
2635 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2636 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
2640 // Set VFR type by FormSet class guid
2642 for (Index
= 0; Index
< 3; Index
++) {
2643 if (CompareGuid (&FormSet
->ClassGuid
[Index
], &gEfiHiiPlatformSetupFormsetGuid
)) {
2644 gClassOfVfr
|= FORMSET_CLASS_PLATFORM_SETUP
;
2649 if ((gClassOfVfr
& FORMSET_CLASS_FRONT_PAGE
) == FORMSET_CLASS_FRONT_PAGE
) {
2650 gFrontPageHandle
= FormSet
->HiiHandle
;
2654 // Match GUID to find out the function key setting. If match fail, use the default setting.
2656 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
2657 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
2659 // Update the function key setting.
2661 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
2663 // Function key prompt can not be displayed if the function key has been disabled.
2665 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2666 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2669 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2670 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2680 Save globals used by previous call to SendForm(). SendForm() may be called from
2681 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
2682 So, save globals of previous call to SendForm() and restore them upon exit.
2686 SaveBrowserContext (
2690 BROWSER_CONTEXT
*Context
;
2692 gBrowserContextCount
++;
2693 if (gBrowserContextCount
== 1) {
2695 // This is not reentry of SendForm(), no context to save
2700 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
2701 ASSERT (Context
!= NULL
);
2703 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
2706 // Save FormBrowser context
2708 Context
->BannerData
= gBannerData
;
2709 Context
->ClassOfVfr
= gClassOfVfr
;
2710 Context
->FunctionKeySetting
= gFunctionKeySetting
;
2711 Context
->ResetRequired
= gResetRequired
;
2712 Context
->NvUpdateRequired
= gNvUpdateRequired
;
2713 Context
->Direction
= gDirection
;
2714 Context
->FunctionNineString
= gFunctionNineString
;
2715 Context
->FunctionTenString
= gFunctionTenString
;
2716 Context
->EnterString
= gEnterString
;
2717 Context
->EnterCommitString
= gEnterCommitString
;
2718 Context
->EnterEscapeString
= gEnterEscapeString
;
2719 Context
->EscapeString
= gEscapeString
;
2720 Context
->SaveFailed
= gSaveFailed
;
2721 Context
->MoveHighlight
= gMoveHighlight
;
2722 Context
->MakeSelection
= gMakeSelection
;
2723 Context
->DecNumericInput
= gDecNumericInput
;
2724 Context
->HexNumericInput
= gHexNumericInput
;
2725 Context
->ToggleCheckBox
= gToggleCheckBox
;
2726 Context
->PromptForData
= gPromptForData
;
2727 Context
->PromptForPassword
= gPromptForPassword
;
2728 Context
->PromptForNewPassword
= gPromptForNewPassword
;
2729 Context
->ConfirmPassword
= gConfirmPassword
;
2730 Context
->ConfirmError
= gConfirmError
;
2731 Context
->PassowordInvalid
= gPassowordInvalid
;
2732 Context
->PressEnter
= gPressEnter
;
2733 Context
->EmptyString
= gEmptyString
;
2734 Context
->AreYouSure
= gAreYouSure
;
2735 Context
->YesResponse
= gYesResponse
;
2736 Context
->NoResponse
= gNoResponse
;
2737 Context
->MiniString
= gMiniString
;
2738 Context
->PlusString
= gPlusString
;
2739 Context
->MinusString
= gMinusString
;
2740 Context
->AdjustNumber
= gAdjustNumber
;
2741 Context
->SaveChanges
= gSaveChanges
;
2742 Context
->OptionMismatch
= gOptionMismatch
;
2743 Context
->FormSuppress
= gFormSuppress
;
2744 Context
->PromptBlockWidth
= gPromptBlockWidth
;
2745 Context
->OptionBlockWidth
= gOptionBlockWidth
;
2746 Context
->HelpBlockWidth
= gHelpBlockWidth
;
2747 Context
->OldFormSet
= gOldFormSet
;
2748 Context
->MenuRefreshHead
= gMenuRefreshHead
;
2750 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
2751 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
2754 // Insert to FormBrowser context list
2756 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
2761 Restore globals used by previous call to SendForm().
2765 RestoreBrowserContext (
2770 BROWSER_CONTEXT
*Context
;
2772 ASSERT (gBrowserContextCount
!= 0);
2773 gBrowserContextCount
--;
2774 if (gBrowserContextCount
== 0) {
2776 // This is not reentry of SendForm(), no context to restore
2781 ASSERT (!IsListEmpty (&gBrowserContextList
));
2783 Link
= GetFirstNode (&gBrowserContextList
);
2784 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
2787 // Restore FormBrowser context
2789 gBannerData
= Context
->BannerData
;
2790 gClassOfVfr
= Context
->ClassOfVfr
;
2791 gFunctionKeySetting
= Context
->FunctionKeySetting
;
2792 gResetRequired
= Context
->ResetRequired
;
2793 gNvUpdateRequired
= Context
->NvUpdateRequired
;
2794 gDirection
= Context
->Direction
;
2795 gFunctionNineString
= Context
->FunctionNineString
;
2796 gFunctionTenString
= Context
->FunctionTenString
;
2797 gEnterString
= Context
->EnterString
;
2798 gEnterCommitString
= Context
->EnterCommitString
;
2799 gEnterEscapeString
= Context
->EnterEscapeString
;
2800 gEscapeString
= Context
->EscapeString
;
2801 gSaveFailed
= Context
->SaveFailed
;
2802 gMoveHighlight
= Context
->MoveHighlight
;
2803 gMakeSelection
= Context
->MakeSelection
;
2804 gDecNumericInput
= Context
->DecNumericInput
;
2805 gHexNumericInput
= Context
->HexNumericInput
;
2806 gToggleCheckBox
= Context
->ToggleCheckBox
;
2807 gPromptForData
= Context
->PromptForData
;
2808 gPromptForPassword
= Context
->PromptForPassword
;
2809 gPromptForNewPassword
= Context
->PromptForNewPassword
;
2810 gConfirmPassword
= Context
->ConfirmPassword
;
2811 gConfirmError
= Context
->ConfirmError
;
2812 gPassowordInvalid
= Context
->PassowordInvalid
;
2813 gPressEnter
= Context
->PressEnter
;
2814 gEmptyString
= Context
->EmptyString
;
2815 gAreYouSure
= Context
->AreYouSure
;
2816 gYesResponse
= Context
->YesResponse
;
2817 gNoResponse
= Context
->NoResponse
;
2818 gMiniString
= Context
->MiniString
;
2819 gPlusString
= Context
->PlusString
;
2820 gMinusString
= Context
->MinusString
;
2821 gAdjustNumber
= Context
->AdjustNumber
;
2822 gSaveChanges
= Context
->SaveChanges
;
2823 gOptionMismatch
= Context
->OptionMismatch
;
2824 gFormSuppress
= Context
->FormSuppress
;
2825 gPromptBlockWidth
= Context
->PromptBlockWidth
;
2826 gOptionBlockWidth
= Context
->OptionBlockWidth
;
2827 gHelpBlockWidth
= Context
->HelpBlockWidth
;
2828 gOldFormSet
= Context
->OldFormSet
;
2829 gMenuRefreshHead
= Context
->MenuRefreshHead
;
2831 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
2832 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
2835 // Remove from FormBrowser context list
2837 RemoveEntryList (&Context
->Link
);
2838 gBS
->FreePool (Context
);