2 Entry and initialization module for the browser.
4 Copyright (c) 2007 - 2011, 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 gPromptBlockWidth
= (CHAR16
) (gOptionBlockWidth
+ LEFT_SKIPPED_COLUMNS
);
272 gHelpBlockWidth
= (CHAR16
) (gOptionBlockWidth
- LEFT_SKIPPED_COLUMNS
);
275 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
277 InitializeBrowserStrings ();
279 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
282 // Ensure we are in Text mode
284 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
286 for (Index
= 0; Index
< HandleCount
; Index
++) {
287 Selection
= AllocateZeroPool (sizeof (UI_MENU_SELECTION
));
288 ASSERT (Selection
!= NULL
);
290 Selection
->Handle
= Handles
[Index
];
291 if (FormSetGuid
!= NULL
) {
292 CopyMem (&Selection
->FormSetGuid
, FormSetGuid
, sizeof (EFI_GUID
));
293 Selection
->FormId
= FormId
;
297 gNvUpdateRequired
= FALSE
;
300 FormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
301 ASSERT (FormSet
!= NULL
);
304 // Initialize internal data structures of FormSet
306 Status
= InitializeFormSet (Selection
->Handle
, &Selection
->FormSetGuid
, FormSet
);
307 if (EFI_ERROR (Status
) || IsListEmpty (&FormSet
->FormListHead
)) {
308 DestroyFormSet (FormSet
);
311 Selection
->FormSet
= FormSet
;
314 // Display this formset
316 gCurrentSelection
= Selection
;
318 Status
= SetupBrowser (Selection
);
320 gCurrentSelection
= NULL
;
322 if (EFI_ERROR (Status
)) {
326 } while (Selection
->Action
== UI_ACTION_REFRESH_FORMSET
);
328 if (gOldFormSet
!= NULL
) {
329 DestroyFormSet (gOldFormSet
);
333 FreePool (Selection
);
336 if (ActionRequest
!= NULL
) {
337 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
338 if (gResetRequired
) {
339 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
343 FreeBrowserStrings ();
345 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
346 gST
->ConOut
->ClearScreen (gST
->ConOut
);
350 // Restore globals used by SendForm()
352 RestoreBrowserContext ();
359 This function is called by a callback handler to retrieve uncommitted state
360 data from the browser.
362 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
364 @param ResultsDataSize A pointer to the size of the buffer associated
366 @param ResultsData A string returned from an IFR browser or
367 equivalent. The results string will have no
368 routing information in them.
369 @param RetrieveData A BOOLEAN field which allows an agent to retrieve
370 (if RetrieveData = TRUE) data from the uncommitted
371 browser state information or set (if RetrieveData
372 = FALSE) data in the uncommitted browser state
374 @param VariableGuid An optional field to indicate the target variable
376 @param VariableName An optional field to indicate the target
377 human-readable variable name.
379 @retval EFI_SUCCESS The results have been distributed or are awaiting
381 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to
382 contain the results data.
388 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
389 IN OUT UINTN
*ResultsDataSize
,
390 IN OUT EFI_STRING ResultsData
,
391 IN BOOLEAN RetrieveData
,
392 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
393 IN CONST CHAR16
*VariableName OPTIONAL
398 FORMSET_STORAGE
*Storage
;
399 FORM_BROWSER_FORMSET
*FormSet
;
406 if (ResultsDataSize
== NULL
|| ResultsData
== NULL
) {
407 return EFI_INVALID_PARAMETER
;
410 if (gCurrentSelection
== NULL
) {
411 return EFI_NOT_READY
;
416 FormSet
= gCurrentSelection
->FormSet
;
419 // Find target storage
421 Link
= GetFirstNode (&FormSet
->StorageListHead
);
422 if (IsNull (&FormSet
->StorageListHead
, Link
)) {
423 return EFI_UNSUPPORTED
;
426 if (VariableGuid
!= NULL
) {
428 // Try to find target storage
431 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
432 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
433 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
435 if (CompareGuid (&Storage
->Guid
, (EFI_GUID
*) VariableGuid
)) {
436 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
438 // Buffer storage require both GUID and Name
440 if (VariableName
== NULL
) {
441 return EFI_NOT_FOUND
;
444 if (StrCmp (Storage
->Name
, (CHAR16
*) VariableName
) != 0) {
454 return EFI_NOT_FOUND
;
458 // GUID/Name is not specified, take the first storage in FormSet
460 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
465 // Skip if there is no RequestElement
467 if (Storage
->ElementCount
== 0) {
472 // Generate <ConfigResp>
474 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
475 if (EFI_ERROR (Status
)) {
480 // Skip <ConfigHdr> and '&' to point to <ConfigBody>
482 StrPtr
= ConfigResp
+ StrLen (Storage
->ConfigHdr
) + 1;
484 BufferSize
= StrSize (StrPtr
);
485 if (*ResultsDataSize
< BufferSize
) {
486 *ResultsDataSize
= BufferSize
;
488 FreePool (ConfigResp
);
489 return EFI_BUFFER_TOO_SMALL
;
492 *ResultsDataSize
= BufferSize
;
493 CopyMem (ResultsData
, StrPtr
, BufferSize
);
495 FreePool (ConfigResp
);
498 // Prepare <ConfigResp>
500 TmpSize
= StrLen (ResultsData
);
501 BufferSize
= (TmpSize
+ StrLen (Storage
->ConfigHdr
) + 2) * sizeof (CHAR16
);
502 ConfigResp
= AllocateZeroPool (BufferSize
);
503 ASSERT (ConfigResp
!= NULL
);
505 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
506 StrCat (ConfigResp
, L
"&");
507 StrCat (ConfigResp
, ResultsData
);
510 // Update Browser uncommited data
512 Status
= ConfigRespToStorage (Storage
, ConfigResp
);
513 if (EFI_ERROR (Status
)) {
523 Initialize Setup Browser driver.
525 @param ImageHandle The image handle.
526 @param SystemTable The system table.
528 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
529 @return Other value if failed to initialize the Setup Browser module.
535 IN EFI_HANDLE ImageHandle
,
536 IN EFI_SYSTEM_TABLE
*SystemTable
542 // Locate required Hii relative protocols
544 Status
= gBS
->LocateProtocol (
545 &gEfiHiiDatabaseProtocolGuid
,
547 (VOID
**) &mHiiDatabase
549 ASSERT_EFI_ERROR (Status
);
551 Status
= gBS
->LocateProtocol (
552 &gEfiHiiStringProtocolGuid
,
554 (VOID
**) &mHiiString
556 ASSERT_EFI_ERROR (Status
);
558 Status
= gBS
->LocateProtocol (
559 &gEfiHiiConfigRoutingProtocolGuid
,
561 (VOID
**) &mHiiConfigRouting
563 ASSERT_EFI_ERROR (Status
);
566 // Publish our HII data
568 gHiiHandle
= HiiAddPackages (
574 ASSERT (gHiiHandle
!= NULL
);
577 // Initialize Driver private data
579 gBannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
580 ASSERT (gBannerData
!= NULL
);
583 // Install FormBrowser2 protocol
585 mPrivateData
.Handle
= NULL
;
586 Status
= gBS
->InstallProtocolInterface (
587 &mPrivateData
.Handle
,
588 &gEfiFormBrowser2ProtocolGuid
,
589 EFI_NATIVE_INTERFACE
,
590 &mPrivateData
.FormBrowser2
592 ASSERT_EFI_ERROR (Status
);
599 Create a new string in HII Package List.
601 @param String The String to be added
602 @param HiiHandle The package list in the HII database to insert the
605 @return The output string.
611 IN EFI_HII_HANDLE HiiHandle
614 EFI_STRING_ID StringId
;
616 StringId
= HiiSetString (HiiHandle
, 0, String
, NULL
);
617 ASSERT (StringId
!= 0);
624 Delete a string from HII Package List.
626 @param StringId Id of the string in HII database.
627 @param HiiHandle The HII package list handle.
629 @retval EFI_SUCCESS The string was deleted successfully.
634 IN EFI_STRING_ID StringId
,
635 IN EFI_HII_HANDLE HiiHandle
640 NullChar
= CHAR_NULL
;
641 HiiSetString (HiiHandle
, StringId
, &NullChar
, NULL
);
647 Get the string based on the StringId and HII Package List Handle.
649 @param Token The String's ID.
650 @param HiiHandle The package list in the HII database to search for
651 the specified string.
653 @return The output string.
658 IN EFI_STRING_ID Token
,
659 IN EFI_HII_HANDLE HiiHandle
664 if (HiiHandle
== NULL
) {
668 String
= HiiGetString (HiiHandle
, Token
, NULL
);
669 if (String
== NULL
) {
670 String
= AllocateCopyPool (sizeof (mUnknownString
), mUnknownString
);
671 ASSERT (String
!= NULL
);
673 return (CHAR16
*) String
;
678 Allocate new memory and then copy the Unicode string Source to Destination.
680 @param Dest Location to copy string
681 @param Src String to copy
686 IN OUT CHAR16
**Dest
,
693 *Dest
= AllocateCopyPool (StrSize (Src
), Src
);
694 ASSERT (*Dest
!= NULL
);
699 Allocate new memory and concatinate Source on the end of Destination.
701 @param Dest String to added to the end of.
702 @param Src String to concatinate.
707 IN OUT CHAR16
**Dest
,
715 NewStringCpy (Dest
, Src
);
719 TmpSize
= StrSize (*Dest
);
720 NewString
= AllocateZeroPool (TmpSize
+ StrSize (Src
) - 1);
721 ASSERT (NewString
!= NULL
);
723 StrCpy (NewString
, *Dest
);
724 StrCat (NewString
, Src
);
732 Synchronize Storage's Edit copy to Shadow copy.
734 @param Storage The Storage to be synchronized.
739 IN FORMSET_STORAGE
*Storage
743 NAME_VALUE_NODE
*Node
;
745 switch (Storage
->Type
) {
746 case EFI_HII_VARSTORE_BUFFER
:
747 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
750 case EFI_HII_VARSTORE_NAME_VALUE
:
751 Link
= GetFirstNode (&Storage
->NameValueListHead
);
752 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
753 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
755 NewStringCpy (&Node
->Value
, Node
->EditValue
);
757 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
761 case EFI_HII_VARSTORE_EFI_VARIABLE
:
769 Get Value for given Name from a NameValue Storage.
771 @param Storage The NameValue Storage.
772 @param Name The Name.
773 @param Value The retured Value.
775 @retval EFI_SUCCESS Value found for given Name.
776 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
781 IN FORMSET_STORAGE
*Storage
,
783 IN OUT CHAR16
**Value
787 NAME_VALUE_NODE
*Node
;
791 Link
= GetFirstNode (&Storage
->NameValueListHead
);
792 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
793 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
795 if (StrCmp (Name
, Node
->Name
) == 0) {
796 NewStringCpy (Value
, Node
->EditValue
);
800 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
803 return EFI_NOT_FOUND
;
808 Set Value of given Name in a NameValue Storage.
810 @param Storage The NameValue Storage.
811 @param Name The Name.
812 @param Value The Value to set.
814 @retval EFI_SUCCESS Value found for given Name.
815 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
820 IN FORMSET_STORAGE
*Storage
,
826 NAME_VALUE_NODE
*Node
;
828 Link
= GetFirstNode (&Storage
->NameValueListHead
);
829 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
830 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
832 if (StrCmp (Name
, Node
->Name
) == 0) {
833 if (Node
->EditValue
!= NULL
) {
834 FreePool (Node
->EditValue
);
836 Node
->EditValue
= AllocateCopyPool (StrSize (Value
), Value
);
837 ASSERT (Node
->EditValue
!= NULL
);
841 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
844 return EFI_NOT_FOUND
;
849 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
851 @param Storage The Storage to be conveted.
852 @param ConfigResp The returned <ConfigResp>.
854 @retval EFI_SUCCESS Convert success.
855 @retval EFI_INVALID_PARAMETER Incorrect storage type.
859 StorageToConfigResp (
860 IN FORMSET_STORAGE
*Storage
,
861 IN CHAR16
**ConfigResp
867 NAME_VALUE_NODE
*Node
;
869 Status
= EFI_SUCCESS
;
871 switch (Storage
->Type
) {
872 case EFI_HII_VARSTORE_BUFFER
:
873 Status
= mHiiConfigRouting
->BlockToConfig (
875 Storage
->ConfigRequest
,
883 case EFI_HII_VARSTORE_NAME_VALUE
:
885 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
887 Link
= GetFirstNode (&Storage
->NameValueListHead
);
888 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
889 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
891 NewStringCat (ConfigResp
, L
"&");
892 NewStringCat (ConfigResp
, Node
->Name
);
893 NewStringCat (ConfigResp
, L
"=");
894 NewStringCat (ConfigResp
, Node
->EditValue
);
896 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
900 case EFI_HII_VARSTORE_EFI_VARIABLE
:
902 Status
= EFI_INVALID_PARAMETER
;
911 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
913 @param Storage The Storage to receive the settings.
914 @param ConfigResp The <ConfigResp> to be converted.
916 @retval EFI_SUCCESS Convert success.
917 @retval EFI_INVALID_PARAMETER Incorrect storage type.
921 ConfigRespToStorage (
922 IN FORMSET_STORAGE
*Storage
,
923 IN CHAR16
*ConfigResp
933 Status
= EFI_SUCCESS
;
935 switch (Storage
->Type
) {
936 case EFI_HII_VARSTORE_BUFFER
:
937 BufferSize
= Storage
->Size
;
938 Status
= mHiiConfigRouting
->ConfigToBlock (
947 case EFI_HII_VARSTORE_NAME_VALUE
:
948 StrPtr
= StrStr (ConfigResp
, L
"PATH");
949 if (StrPtr
== NULL
) {
952 StrPtr
= StrStr (ConfigResp
, L
"&");
953 while (StrPtr
!= NULL
) {
959 StrPtr
= StrStr (StrPtr
, L
"=");
960 if (StrPtr
== NULL
) {
970 StrPtr
= StrStr (StrPtr
, L
"&");
971 if (StrPtr
!= NULL
) {
974 SetValueByName (Storage
, Name
, Value
);
978 case EFI_HII_VARSTORE_EFI_VARIABLE
:
980 Status
= EFI_INVALID_PARAMETER
;
989 Get Question's current Value.
991 @param FormSet FormSet data structure.
992 @param Form Form data structure.
993 @param Question Question to be initialized.
994 @param Cached TRUE: get from Edit copy FALSE: get from original
997 @retval EFI_SUCCESS The function completed successfully.
1002 IN FORM_BROWSER_FORMSET
*FormSet
,
1003 IN FORM_BROWSER_FORM
*Form
,
1004 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1014 FORMSET_STORAGE
*Storage
;
1015 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1016 CHAR16
*ConfigRequest
;
1024 BOOLEAN IsBufferStorage
;
1029 Status
= EFI_SUCCESS
;
1032 // Statement don't have storage, skip them
1034 if (Question
->QuestionId
== 0) {
1039 // Question value is provided by an Expression, evaluate it
1041 if (Question
->ValueExpression
!= NULL
) {
1042 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1043 if (!EFI_ERROR (Status
)) {
1044 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1050 // Get question value by read expression.
1052 if (Question
->ReadExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1053 Status
= EvaluateExpression (FormSet
, Form
, Question
->ReadExpression
);
1054 if (!EFI_ERROR (Status
) && (Question
->ReadExpression
->Result
.Type
< EFI_IFR_TYPE_OTHER
)) {
1056 // Only update question value to the valid result.
1058 CopyMem (&Question
->HiiValue
, &Question
->ReadExpression
->Result
, sizeof (EFI_HII_VALUE
));
1064 // Question value is provided by RTC
1066 Storage
= Question
->Storage
;
1067 QuestionValue
= &Question
->HiiValue
.Value
;
1068 if (Storage
== NULL
) {
1070 // It's a Question without storage, or RTC date/time
1072 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1074 // Date and time define the same Flags bit
1076 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1077 case QF_DATE_STORAGE_TIME
:
1078 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1081 case QF_DATE_STORAGE_WAKEUP
:
1082 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1085 case QF_DATE_STORAGE_NORMAL
:
1088 // For date/time without storage
1093 if (EFI_ERROR (Status
)) {
1097 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1098 QuestionValue
->date
.Year
= EfiTime
.Year
;
1099 QuestionValue
->date
.Month
= EfiTime
.Month
;
1100 QuestionValue
->date
.Day
= EfiTime
.Day
;
1102 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1103 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1104 QuestionValue
->time
.Second
= EfiTime
.Second
;
1112 // Question value is provided by EFI variable
1114 StorageWidth
= Question
->StorageWidth
;
1115 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1116 if (Question
->BufferValue
!= NULL
) {
1117 Dst
= Question
->BufferValue
;
1119 Dst
= (UINT8
*) QuestionValue
;
1122 Status
= gRT
->GetVariable (
1123 Question
->VariableName
,
1130 // Always return success, even this EFI variable doesn't exist
1136 // Question Value is provided by Buffer Storage or NameValue Storage
1138 if (Question
->BufferValue
!= NULL
) {
1140 // This Question is password or orderedlist
1142 Dst
= Question
->BufferValue
;
1145 // Other type of Questions
1147 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1150 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1151 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1153 if (IsBufferStorage
) {
1155 // Copy from storage Edit buffer
1157 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1160 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1161 if (EFI_ERROR (Status
)) {
1165 ASSERT (Value
!= NULL
);
1166 LengthStr
= StrLen (Value
);
1167 Status
= EFI_SUCCESS
;
1170 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1171 // Add string tail char L'\0' into Length
1173 Length
= StorageWidth
+ sizeof (CHAR16
);
1174 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1175 Status
= EFI_BUFFER_TOO_SMALL
;
1177 StringPtr
= (CHAR16
*) Dst
;
1178 ZeroMem (TemStr
, sizeof (TemStr
));
1179 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1180 StrnCpy (TemStr
, Value
+ Index
, 4);
1181 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1184 // Add tailing L'\0' character
1186 StringPtr
[Index
/4] = L
'\0';
1189 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1190 Status
= EFI_BUFFER_TOO_SMALL
;
1192 ZeroMem (TemStr
, sizeof (TemStr
));
1193 for (Index
= 0; Index
< LengthStr
; Index
++) {
1194 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1195 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1196 if ((Index
& 1) == 0) {
1197 Dst
[Index
/2] = DigitUint8
;
1199 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1209 // Request current settings from Configuration Driver
1211 if (FormSet
->ConfigAccess
== NULL
) {
1212 return EFI_NOT_FOUND
;
1216 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1217 // <ConfigHdr> + "&" + <VariableName>
1219 if (IsBufferStorage
) {
1220 Length
= StrLen (Storage
->ConfigHdr
);
1221 Length
+= StrLen (Question
->BlockName
);
1223 Length
= StrLen (Storage
->ConfigHdr
);
1224 Length
+= StrLen (Question
->VariableName
) + 1;
1226 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1227 ASSERT (ConfigRequest
!= NULL
);
1229 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1230 if (IsBufferStorage
) {
1231 StrCat (ConfigRequest
, Question
->BlockName
);
1233 StrCat (ConfigRequest
, L
"&");
1234 StrCat (ConfigRequest
, Question
->VariableName
);
1237 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1238 FormSet
->ConfigAccess
,
1243 if (EFI_ERROR (Status
)) {
1248 // Skip <ConfigRequest>
1250 Value
= Result
+ Length
;
1251 if (IsBufferStorage
) {
1257 if (*Value
!= '=') {
1259 return EFI_NOT_FOUND
;
1262 // Skip '=', point to value
1267 // Suppress <AltResp> if any
1270 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1275 LengthStr
= StrLen (Value
);
1276 Status
= EFI_SUCCESS
;
1277 if (!IsBufferStorage
&& IsString
) {
1279 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1280 // Add string tail char L'\0' into Length
1282 Length
= StorageWidth
+ sizeof (CHAR16
);
1283 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1284 Status
= EFI_BUFFER_TOO_SMALL
;
1286 StringPtr
= (CHAR16
*) Dst
;
1287 ZeroMem (TemStr
, sizeof (TemStr
));
1288 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1289 StrnCpy (TemStr
, Value
+ Index
, 4);
1290 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1293 // Add tailing L'\0' character
1295 StringPtr
[Index
/4] = L
'\0';
1298 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1299 Status
= EFI_BUFFER_TOO_SMALL
;
1301 ZeroMem (TemStr
, sizeof (TemStr
));
1302 for (Index
= 0; Index
< LengthStr
; Index
++) {
1303 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1304 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1305 if ((Index
& 1) == 0) {
1306 Dst
[Index
/2] = DigitUint8
;
1308 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1314 if (EFI_ERROR (Status
)) {
1320 // Synchronize Edit Buffer
1322 if (IsBufferStorage
) {
1323 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1325 SetValueByName (Storage
, Question
->VariableName
, Value
);
1336 Save Question Value to edit copy(cached) or Storage(uncached).
1338 @param FormSet FormSet data structure.
1339 @param Form Form data structure.
1340 @param Question Pointer to the Question.
1341 @param Cached TRUE: set to Edit copy FALSE: set to original
1344 @retval EFI_SUCCESS The function completed successfully.
1349 IN FORM_BROWSER_FORMSET
*FormSet
,
1350 IN FORM_BROWSER_FORM
*Form
,
1351 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1362 FORMSET_STORAGE
*Storage
;
1363 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1368 BOOLEAN IsBufferStorage
;
1375 Status
= EFI_SUCCESS
;
1378 // Statement don't have storage, skip them
1380 if (Question
->QuestionId
== 0) {
1385 // If Question value is provided by an Expression, then it is read only
1387 if (Question
->ValueExpression
!= NULL
) {
1392 // Before set question value, evaluate its write expression.
1394 if (Question
->WriteExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1395 Status
= EvaluateExpression (FormSet
, Form
, Question
->WriteExpression
);
1396 if (EFI_ERROR (Status
)) {
1402 // Question value is provided by RTC
1404 Storage
= Question
->Storage
;
1405 QuestionValue
= &Question
->HiiValue
.Value
;
1406 if (Storage
== NULL
) {
1408 // It's a Question without storage, or RTC date/time
1410 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1412 // Date and time define the same Flags bit
1414 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1415 case QF_DATE_STORAGE_TIME
:
1416 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1419 case QF_DATE_STORAGE_WAKEUP
:
1420 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1423 case QF_DATE_STORAGE_NORMAL
:
1426 // For date/time without storage
1431 if (EFI_ERROR (Status
)) {
1435 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1436 EfiTime
.Year
= QuestionValue
->date
.Year
;
1437 EfiTime
.Month
= QuestionValue
->date
.Month
;
1438 EfiTime
.Day
= QuestionValue
->date
.Day
;
1440 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1441 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1442 EfiTime
.Second
= QuestionValue
->time
.Second
;
1445 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1446 Status
= gRT
->SetTime (&EfiTime
);
1448 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1456 // Question value is provided by EFI variable
1458 StorageWidth
= Question
->StorageWidth
;
1459 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1460 if (Question
->BufferValue
!= NULL
) {
1461 Src
= Question
->BufferValue
;
1463 Src
= (UINT8
*) QuestionValue
;
1466 Status
= gRT
->SetVariable (
1467 Question
->VariableName
,
1469 Storage
->Attributes
,
1477 // Question Value is provided by Buffer Storage or NameValue Storage
1479 if (Question
->BufferValue
!= NULL
) {
1480 Src
= Question
->BufferValue
;
1482 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1485 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1486 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1487 if (IsBufferStorage
) {
1489 // Copy to storage edit buffer
1491 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1495 // Allocate enough string buffer.
1498 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1499 Value
= AllocateZeroPool (BufferLen
);
1500 ASSERT (Value
!= NULL
);
1502 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1504 TemName
= (CHAR16
*) Src
;
1506 for (; *TemName
!= L
'\0'; TemName
++) {
1507 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1510 BufferLen
= StorageWidth
* 2 + 1;
1511 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1512 ASSERT (Value
!= NULL
);
1514 // Convert Buffer to Hex String
1516 TemBuffer
= Src
+ StorageWidth
- 1;
1518 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1519 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1523 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
);
1529 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1530 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1532 if (IsBufferStorage
) {
1533 Length
= StrLen (Question
->BlockName
) + 7;
1535 Length
= StrLen (Question
->VariableName
) + 2;
1537 if (!IsBufferStorage
&& IsString
) {
1538 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1540 Length
+= (StorageWidth
* 2);
1542 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1543 ASSERT (ConfigResp
!= NULL
);
1545 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1546 if (IsBufferStorage
) {
1547 StrCat (ConfigResp
, Question
->BlockName
);
1548 StrCat (ConfigResp
, L
"&VALUE=");
1550 StrCat (ConfigResp
, L
"&");
1551 StrCat (ConfigResp
, Question
->VariableName
);
1552 StrCat (ConfigResp
, L
"=");
1555 Value
= ConfigResp
+ StrLen (ConfigResp
);
1557 if (!IsBufferStorage
&& IsString
) {
1559 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1561 TemName
= (CHAR16
*) Src
;
1563 for (; *TemName
!= L
'\0'; TemName
++) {
1564 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1568 // Convert Buffer to Hex String
1570 TemBuffer
= Src
+ StorageWidth
- 1;
1572 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1573 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1578 // Convert to lower char.
1580 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1581 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1582 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1587 // Submit Question Value to Configuration Driver
1589 if (FormSet
->ConfigAccess
!= NULL
) {
1590 Status
= FormSet
->ConfigAccess
->RouteConfig (
1591 FormSet
->ConfigAccess
,
1595 if (EFI_ERROR (Status
)) {
1596 FreePool (ConfigResp
);
1600 FreePool (ConfigResp
);
1603 // Synchronize shadow Buffer
1605 SynchronizeStorage (Storage
);
1613 Perform inconsistent check for a Form.
1615 @param FormSet FormSet data structure.
1616 @param Form Form data structure.
1617 @param Question The Question to be validated.
1618 @param Type Validation type: InConsistent or NoSubmit
1620 @retval EFI_SUCCESS Form validation pass.
1621 @retval other Form validation failed.
1626 IN FORM_BROWSER_FORMSET
*FormSet
,
1627 IN FORM_BROWSER_FORM
*Form
,
1628 IN FORM_BROWSER_STATEMENT
*Question
,
1634 LIST_ENTRY
*ListHead
;
1637 FORM_EXPRESSION
*Expression
;
1639 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1640 ListHead
= &Question
->InconsistentListHead
;
1641 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1642 ListHead
= &Question
->NoSubmitListHead
;
1644 return EFI_UNSUPPORTED
;
1647 Link
= GetFirstNode (ListHead
);
1648 while (!IsNull (ListHead
, Link
)) {
1649 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1652 // Evaluate the expression
1654 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1655 if (EFI_ERROR (Status
)) {
1659 if (Expression
->Result
.Value
.b
) {
1661 // Condition meet, show up error message
1663 if (Expression
->Error
!= 0) {
1664 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1666 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1667 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1671 return EFI_NOT_READY
;
1674 Link
= GetNextNode (ListHead
, Link
);
1682 Perform NoSubmit check for each Form in FormSet.
1684 @param FormSet FormSet data structure.
1686 @retval EFI_SUCCESS Form validation pass.
1687 @retval other Form validation failed.
1692 IN FORM_BROWSER_FORMSET
*FormSet
1697 FORM_BROWSER_STATEMENT
*Question
;
1698 FORM_BROWSER_FORM
*Form
;
1699 LIST_ENTRY
*LinkForm
;
1701 LinkForm
= GetFirstNode (&FormSet
->FormListHead
);
1702 while (!IsNull (&FormSet
->FormListHead
, LinkForm
)) {
1703 Form
= FORM_BROWSER_FORM_FROM_LINK (LinkForm
);
1705 Link
= GetFirstNode (&Form
->StatementListHead
);
1706 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1707 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1709 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1710 if (EFI_ERROR (Status
)) {
1714 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1717 LinkForm
= GetNextNode (&FormSet
->FormListHead
, LinkForm
);
1727 @param FormSet FormSet data structure.
1728 @param Form Form data structure.
1730 @retval EFI_SUCCESS The function completed successfully.
1735 IN FORM_BROWSER_FORMSET
*FormSet
,
1736 IN FORM_BROWSER_FORM
*Form
1741 EFI_STRING ConfigResp
;
1742 EFI_STRING Progress
;
1743 FORMSET_STORAGE
*Storage
;
1746 // Validate the Form by NoSubmit check
1748 Status
= NoSubmitCheck (FormSet
);
1749 if (EFI_ERROR (Status
)) {
1754 // Submit Buffer storage or Name/Value storage
1756 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1757 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1758 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1759 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1761 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1766 // Skip if there is no RequestElement
1768 if (Storage
->ElementCount
== 0) {
1773 // Prepare <ConfigResp>
1775 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
1776 if (EFI_ERROR (Status
)) {
1781 // Send <ConfigResp> to Configuration Driver
1783 if (FormSet
->ConfigAccess
!= NULL
) {
1784 Status
= FormSet
->ConfigAccess
->RouteConfig (
1785 FormSet
->ConfigAccess
,
1789 if (EFI_ERROR (Status
)) {
1790 FreePool (ConfigResp
);
1794 FreePool (ConfigResp
);
1797 // Config success, update storage shadow Buffer
1799 SynchronizeStorage (Storage
);
1802 gNvUpdateRequired
= FALSE
;
1809 Reset Question to its default value.
1811 @param FormSet The form set.
1812 @param Form The form.
1813 @param Question The question.
1814 @param DefaultId The Class of the default.
1816 @retval EFI_SUCCESS Question is reset to default value.
1820 GetQuestionDefault (
1821 IN FORM_BROWSER_FORMSET
*FormSet
,
1822 IN FORM_BROWSER_FORM
*Form
,
1823 IN FORM_BROWSER_STATEMENT
*Question
,
1829 QUESTION_DEFAULT
*Default
;
1830 QUESTION_OPTION
*Option
;
1831 EFI_HII_VALUE
*HiiValue
;
1833 EFI_STRING StrValue
;
1835 Status
= EFI_SUCCESS
;
1839 // Statement don't have storage, skip them
1841 if (Question
->QuestionId
== 0) {
1846 // There are three ways to specify default value for a Question:
1847 // 1, use nested EFI_IFR_DEFAULT (highest priority)
1848 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
1849 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
1851 HiiValue
= &Question
->HiiValue
;
1854 // EFI_IFR_DEFAULT has highest priority
1856 if (!IsListEmpty (&Question
->DefaultListHead
)) {
1857 Link
= GetFirstNode (&Question
->DefaultListHead
);
1858 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
1859 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1861 if (Default
->DefaultId
== DefaultId
) {
1862 if (Default
->ValueExpression
!= NULL
) {
1864 // Default is provided by an Expression, evaluate it
1866 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
1867 if (EFI_ERROR (Status
)) {
1871 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1874 // Default value is embedded in EFI_IFR_DEFAULT
1876 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
1879 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1880 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
1881 if (StrValue
== NULL
) {
1882 return EFI_NOT_FOUND
;
1884 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
1890 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
1895 // EFI_ONE_OF_OPTION
1897 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
1898 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1900 // OneOfOption could only provide Standard and Manufacturing default
1902 Link
= GetFirstNode (&Question
->OptionListHead
);
1903 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1904 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1906 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
1907 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
1909 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1914 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1920 // EFI_IFR_CHECKBOX - lowest priority
1922 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
1923 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1925 // Checkbox could only provide Standard and Manufacturing default
1927 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
1928 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
1930 HiiValue
->Value
.b
= TRUE
;
1932 HiiValue
->Value
.b
= FALSE
;
1940 // For Questions without default
1942 switch (Question
->Operand
) {
1943 case EFI_IFR_NUMERIC_OP
:
1945 // Take minimum value as numeric default value
1947 if ((HiiValue
->Value
.u64
< Question
->Minimum
) || (HiiValue
->Value
.u64
> Question
->Maximum
)) {
1948 HiiValue
->Value
.u64
= Question
->Minimum
;
1952 case EFI_IFR_ONE_OF_OP
:
1954 // Take first oneof option as oneof's default value
1956 if (ValueToOption (Question
, HiiValue
) == NULL
) {
1957 Link
= GetFirstNode (&Question
->OptionListHead
);
1958 if (!IsNull (&Question
->OptionListHead
, Link
)) {
1959 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1960 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1965 case EFI_IFR_ORDERED_LIST_OP
:
1967 // Take option sequence in IFR as ordered list's default value
1970 Link
= GetFirstNode (&Question
->OptionListHead
);
1971 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1972 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1974 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
1977 if (Index
>= Question
->MaxContainers
) {
1981 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1986 Status
= EFI_NOT_FOUND
;
1995 Reset Questions in a Form to their default value.
1997 @param FormSet FormSet data structure.
1998 @param Form The Form which to be reset.
1999 @param DefaultId The Class of the default.
2001 @retval EFI_SUCCESS The function completed successfully.
2005 ExtractFormDefault (
2006 IN FORM_BROWSER_FORMSET
*FormSet
,
2007 IN FORM_BROWSER_FORM
*Form
,
2013 FORM_BROWSER_STATEMENT
*Question
;
2015 Link
= GetFirstNode (&Form
->StatementListHead
);
2016 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2017 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2018 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2021 // If Question is disabled, don't reset it to default
2023 if (Question
->DisableExpression
!= NULL
) {
2024 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
2025 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
2031 // Reset Question to its default value
2033 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
2034 if (EFI_ERROR (Status
)) {
2039 // Synchronize Buffer storage's Edit buffer
2041 if ((Question
->Storage
!= NULL
) &&
2042 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
2043 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2051 Initialize Question's Edit copy from Storage.
2053 @param Selection Selection contains the information about
2054 the Selection, form and formset to be displayed.
2055 Selection action may be updated in retrieve callback.
2056 @param FormSet FormSet data structure.
2057 @param Form Form data structure.
2059 @retval EFI_SUCCESS The function completed successfully.
2064 IN OUT UI_MENU_SELECTION
*Selection
,
2065 IN FORM_BROWSER_FORMSET
*FormSet
,
2066 IN FORM_BROWSER_FORM
*Form
2071 FORM_BROWSER_STATEMENT
*Question
;
2074 EFI_HII_VALUE
*HiiValue
;
2075 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2077 Link
= GetFirstNode (&Form
->StatementListHead
);
2078 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2079 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2082 // Initialize local copy of Value for each Question
2084 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2085 if (EFI_ERROR (Status
)) {
2089 if ((Question
->Operand
== EFI_IFR_STRING_OP
) || (Question
->Operand
== EFI_IFR_PASSWORD_OP
)) {
2090 HiiSetString (FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, (CHAR16
*)Question
->BufferValue
, NULL
);
2094 // Check whether EfiVarstore with CallBack can be got.
2096 if ((FormSet
->ConfigAccess
!= NULL
) &&
2097 (Selection
->Action
!= UI_ACTION_REFRESH_FORMSET
) &&
2098 (Question
->QuestionId
!= 0) &&
2099 (Question
->Storage
!= NULL
) &&
2100 (Question
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) &&
2101 ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
2104 // Check QuestionValue does exist.
2106 StorageWidth
= Question
->StorageWidth
;
2107 if (Question
->BufferValue
!= NULL
) {
2108 BufferValue
= Question
->BufferValue
;
2110 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2112 Status
= gRT
->GetVariable (
2113 Question
->VariableName
,
2114 &Question
->Storage
->Guid
,
2120 if (!EFI_ERROR (Status
)) {
2121 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2122 HiiValue
= &Question
->HiiValue
;
2123 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2124 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2125 BufferValue
= Question
->BufferValue
;
2128 Status
= FormSet
->ConfigAccess
->Callback (
2129 FormSet
->ConfigAccess
,
2130 EFI_BROWSER_ACTION_RETRIEVE
,
2131 Question
->QuestionId
,
2133 (EFI_IFR_TYPE_VALUE
*) BufferValue
,
2136 if (!EFI_ERROR (Status
)) {
2137 switch (ActionRequest
) {
2138 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2139 gResetRequired
= TRUE
;
2142 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2144 // Till now there is no uncommitted data, so ignore this request
2148 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2149 Selection
->Action
= UI_ACTION_EXIT
;
2159 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2166 Initialize Question's Edit copy from Storage for the whole Formset.
2168 @param Selection Selection contains the information about
2169 the Selection, form and formset to be displayed.
2170 Selection action may be updated in retrieve callback.
2171 @param FormSet FormSet data structure.
2173 @retval EFI_SUCCESS The function completed successfully.
2178 IN OUT UI_MENU_SELECTION
*Selection
,
2179 IN FORM_BROWSER_FORMSET
*FormSet
2184 FORM_BROWSER_FORM
*Form
;
2186 Link
= GetFirstNode (&FormSet
->FormListHead
);
2187 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2188 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2191 // Initialize local copy of Value for each Form
2193 Status
= LoadFormConfig (Selection
, FormSet
, Form
);
2194 if (EFI_ERROR (Status
)) {
2198 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2205 Fill storage's edit copy with settings requested from Configuration Driver.
2207 @param FormSet FormSet data structure.
2208 @param Storage Buffer Storage.
2210 @retval EFI_SUCCESS The function completed successfully.
2215 IN FORM_BROWSER_FORMSET
*FormSet
,
2216 IN FORMSET_STORAGE
*Storage
2220 EFI_STRING Progress
;
2224 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2228 if (FormSet
->ConfigAccess
== NULL
) {
2229 return EFI_NOT_FOUND
;
2232 if (Storage
->ElementCount
== 0) {
2234 // Skip if there is no RequestElement
2240 // Request current settings from Configuration Driver
2242 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2243 FormSet
->ConfigAccess
,
2244 Storage
->ConfigRequest
,
2248 if (EFI_ERROR (Status
)) {
2253 // Convert Result from <ConfigAltResp> to <ConfigResp>
2255 StrPtr
= StrStr (Result
, L
"ALTCFG");
2256 if (StrPtr
!= NULL
) {
2260 Status
= ConfigRespToStorage (Storage
, Result
);
2267 Copy uncommitted data from source Storage to destination Storage.
2269 @param Dst Target Storage for uncommitted data.
2270 @param Src Source Storage for uncommitted data.
2272 @retval EFI_SUCCESS The function completed successfully.
2273 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2278 IN OUT FORMSET_STORAGE
*Dst
,
2279 IN FORMSET_STORAGE
*Src
2283 NAME_VALUE_NODE
*Node
;
2285 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2286 return EFI_INVALID_PARAMETER
;
2289 switch (Src
->Type
) {
2290 case EFI_HII_VARSTORE_BUFFER
:
2291 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
2294 case EFI_HII_VARSTORE_NAME_VALUE
:
2295 Link
= GetFirstNode (&Src
->NameValueListHead
);
2296 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
2297 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2299 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
);
2301 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
2305 case EFI_HII_VARSTORE_EFI_VARIABLE
:
2315 Get current setting of Questions.
2317 @param FormSet FormSet data structure.
2319 @retval EFI_SUCCESS The function completed successfully.
2323 InitializeCurrentSetting (
2324 IN OUT FORM_BROWSER_FORMSET
*FormSet
2329 FORMSET_STORAGE
*Storage
;
2330 FORMSET_STORAGE
*StorageSrc
;
2331 FORMSET_STORAGE
*OldStorage
;
2332 FORM_BROWSER_FORM
*Form
;
2336 // Extract default from IFR binary
2338 Link
= GetFirstNode (&FormSet
->FormListHead
);
2339 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2340 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2342 Status
= ExtractFormDefault (FormSet
, Form
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2344 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2348 // Request current settings from Configuration Driver
2350 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2351 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2352 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2355 if (gOldFormSet
!= NULL
) {
2357 // Try to find the Storage in backup formset gOldFormSet
2359 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
2360 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
2361 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
2363 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
2364 OldStorage
= StorageSrc
;
2368 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
2372 if (OldStorage
== NULL
) {
2374 // Storage is not found in backup formset, request it from ConfigDriver
2376 Status
= LoadStorage (FormSet
, Storage
);
2379 // Storage found in backup formset, use it
2381 Status
= CopyStorage (Storage
, OldStorage
);
2385 // Now Edit Buffer is filled with default values(lower priority) and current
2386 // settings(higher priority), sychronize it to shadow Buffer
2388 if (!EFI_ERROR (Status
)) {
2389 SynchronizeStorage (Storage
);
2392 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2400 Fetch the Ifr binary data of a FormSet.
2402 @param Handle PackageList Handle
2403 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2404 specified (NULL or zero GUID), take the first
2405 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2406 found in package list.
2407 On output, GUID of the formset found(if not NULL).
2408 @param BinaryLength The length of the FormSet IFR binary.
2409 @param BinaryData The buffer designed to receive the FormSet.
2411 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
2412 BufferLength was updated.
2413 @retval EFI_INVALID_PARAMETER The handle is unknown.
2414 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
2415 be found with the requested FormId.
2420 IN EFI_HII_HANDLE Handle
,
2421 IN OUT EFI_GUID
*FormSetGuid
,
2422 OUT UINTN
*BinaryLength
,
2423 OUT UINT8
**BinaryData
2427 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2433 UINT32 PackageListLength
;
2434 EFI_HII_PACKAGE_HEADER PackageHeader
;
2436 UINT8 NumberOfClassGuid
;
2437 BOOLEAN ClassGuidMatch
;
2438 EFI_GUID
*ClassGuid
;
2439 EFI_GUID
*ComparingGuid
;
2443 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2446 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
2448 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
2449 ComparingGuid
= &gEfiHiiPlatformSetupFormsetGuid
;
2451 ComparingGuid
= FormSetGuid
;
2455 // Get HII PackageList
2458 HiiPackageList
= NULL
;
2459 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2460 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2461 HiiPackageList
= AllocatePool (BufferSize
);
2462 ASSERT (HiiPackageList
!= NULL
);
2464 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2466 if (EFI_ERROR (Status
)) {
2469 ASSERT (HiiPackageList
!= NULL
);
2472 // Get Form package from this HII package List
2474 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2476 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
2478 ClassGuidMatch
= FALSE
;
2479 while (Offset
< PackageListLength
) {
2480 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
2481 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2483 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
2485 // Search FormSet in this Form Package
2487 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
2488 while (Offset2
< PackageHeader
.Length
) {
2489 OpCodeData
= Package
+ Offset2
;
2491 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
2493 // Try to compare against formset GUID
2495 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2499 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
2501 // Try to compare against formset class GUID
2503 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2504 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
2505 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
2506 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
2507 ClassGuidMatch
= TRUE
;
2511 if (ClassGuidMatch
) {
2514 } else if (ComparingGuid
== &gEfiHiiPlatformSetupFormsetGuid
) {
2515 ClassGuidMatch
= TRUE
;
2520 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
2523 if (Offset2
< PackageHeader
.Length
) {
2525 // Target formset found
2531 Offset
+= PackageHeader
.Length
;
2534 if (Offset
>= PackageListLength
) {
2536 // Form package not found in this Package List
2538 FreePool (HiiPackageList
);
2539 return EFI_NOT_FOUND
;
2542 if (ClassGuidMatch
&& (FormSetGuid
!= NULL
)) {
2544 // Return the FormSet GUID
2546 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2550 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
2551 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
2552 // of the Form Package.
2554 *BinaryLength
= PackageHeader
.Length
- Offset2
;
2555 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
2557 FreePool (HiiPackageList
);
2559 if (*BinaryData
== NULL
) {
2560 return EFI_OUT_OF_RESOURCES
;
2568 Initialize the internal data structure of a FormSet.
2570 @param Handle PackageList Handle
2571 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2572 specified (NULL or zero GUID), take the first
2573 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2574 found in package list.
2575 On output, GUID of the formset found(if not NULL).
2576 @param FormSet FormSet data structure.
2578 @retval EFI_SUCCESS The function completed successfully.
2579 @retval EFI_NOT_FOUND The specified FormSet could not be found.
2584 IN EFI_HII_HANDLE Handle
,
2585 IN OUT EFI_GUID
*FormSetGuid
,
2586 OUT FORM_BROWSER_FORMSET
*FormSet
2590 EFI_HANDLE DriverHandle
;
2593 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
2594 if (EFI_ERROR (Status
)) {
2598 FormSet
->HiiHandle
= Handle
;
2599 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
2602 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
2604 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
2605 if (EFI_ERROR (Status
)) {
2608 FormSet
->DriverHandle
= DriverHandle
;
2609 Status
= gBS
->HandleProtocol (
2611 &gEfiHiiConfigAccessProtocolGuid
,
2612 (VOID
**) &FormSet
->ConfigAccess
2614 if (EFI_ERROR (Status
)) {
2616 // Configuration Driver don't attach ConfigAccess protocol to its HII package
2617 // list, then there will be no configuration action required
2619 FormSet
->ConfigAccess
= NULL
;
2623 // Parse the IFR binary OpCodes
2625 Status
= ParseOpCodes (FormSet
);
2626 if (EFI_ERROR (Status
)) {
2631 // Set VFR type by FormSet SubClass field
2633 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
2634 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2635 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
2639 // Set VFR type by FormSet class guid
2641 for (Index
= 0; Index
< 3; Index
++) {
2642 if (CompareGuid (&FormSet
->ClassGuid
[Index
], &gEfiHiiPlatformSetupFormsetGuid
)) {
2643 gClassOfVfr
|= FORMSET_CLASS_PLATFORM_SETUP
;
2648 if ((gClassOfVfr
& FORMSET_CLASS_FRONT_PAGE
) == FORMSET_CLASS_FRONT_PAGE
) {
2649 gFrontPageHandle
= FormSet
->HiiHandle
;
2653 // Match GUID to find out the function key setting. If match fail, use the default setting.
2655 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
2656 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
2658 // Update the function key setting.
2660 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
2662 // Function key prompt can not be displayed if the function key has been disabled.
2664 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2665 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2668 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2669 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2679 Save globals used by previous call to SendForm(). SendForm() may be called from
2680 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
2681 So, save globals of previous call to SendForm() and restore them upon exit.
2685 SaveBrowserContext (
2689 BROWSER_CONTEXT
*Context
;
2691 gBrowserContextCount
++;
2692 if (gBrowserContextCount
== 1) {
2694 // This is not reentry of SendForm(), no context to save
2699 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
2700 ASSERT (Context
!= NULL
);
2702 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
2705 // Save FormBrowser context
2707 Context
->BannerData
= gBannerData
;
2708 Context
->ClassOfVfr
= gClassOfVfr
;
2709 Context
->FunctionKeySetting
= gFunctionKeySetting
;
2710 Context
->ResetRequired
= gResetRequired
;
2711 Context
->NvUpdateRequired
= gNvUpdateRequired
;
2712 Context
->Direction
= gDirection
;
2713 Context
->FunctionNineString
= gFunctionNineString
;
2714 Context
->FunctionTenString
= gFunctionTenString
;
2715 Context
->EnterString
= gEnterString
;
2716 Context
->EnterCommitString
= gEnterCommitString
;
2717 Context
->EnterEscapeString
= gEnterEscapeString
;
2718 Context
->EscapeString
= gEscapeString
;
2719 Context
->SaveFailed
= gSaveFailed
;
2720 Context
->MoveHighlight
= gMoveHighlight
;
2721 Context
->MakeSelection
= gMakeSelection
;
2722 Context
->DecNumericInput
= gDecNumericInput
;
2723 Context
->HexNumericInput
= gHexNumericInput
;
2724 Context
->ToggleCheckBox
= gToggleCheckBox
;
2725 Context
->PromptForData
= gPromptForData
;
2726 Context
->PromptForPassword
= gPromptForPassword
;
2727 Context
->PromptForNewPassword
= gPromptForNewPassword
;
2728 Context
->ConfirmPassword
= gConfirmPassword
;
2729 Context
->ConfirmError
= gConfirmError
;
2730 Context
->PassowordInvalid
= gPassowordInvalid
;
2731 Context
->PressEnter
= gPressEnter
;
2732 Context
->EmptyString
= gEmptyString
;
2733 Context
->AreYouSure
= gAreYouSure
;
2734 Context
->YesResponse
= gYesResponse
;
2735 Context
->NoResponse
= gNoResponse
;
2736 Context
->MiniString
= gMiniString
;
2737 Context
->PlusString
= gPlusString
;
2738 Context
->MinusString
= gMinusString
;
2739 Context
->AdjustNumber
= gAdjustNumber
;
2740 Context
->SaveChanges
= gSaveChanges
;
2741 Context
->OptionMismatch
= gOptionMismatch
;
2742 Context
->FormSuppress
= gFormSuppress
;
2743 Context
->PromptBlockWidth
= gPromptBlockWidth
;
2744 Context
->OptionBlockWidth
= gOptionBlockWidth
;
2745 Context
->HelpBlockWidth
= gHelpBlockWidth
;
2746 Context
->OldFormSet
= gOldFormSet
;
2747 Context
->MenuRefreshHead
= gMenuRefreshHead
;
2749 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
2750 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
2753 // Insert to FormBrowser context list
2755 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
2760 Restore globals used by previous call to SendForm().
2764 RestoreBrowserContext (
2769 BROWSER_CONTEXT
*Context
;
2771 ASSERT (gBrowserContextCount
!= 0);
2772 gBrowserContextCount
--;
2773 if (gBrowserContextCount
== 0) {
2775 // This is not reentry of SendForm(), no context to restore
2780 ASSERT (!IsListEmpty (&gBrowserContextList
));
2782 Link
= GetFirstNode (&gBrowserContextList
);
2783 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
2786 // Restore FormBrowser context
2788 gBannerData
= Context
->BannerData
;
2789 gClassOfVfr
= Context
->ClassOfVfr
;
2790 gFunctionKeySetting
= Context
->FunctionKeySetting
;
2791 gResetRequired
= Context
->ResetRequired
;
2792 gNvUpdateRequired
= Context
->NvUpdateRequired
;
2793 gDirection
= Context
->Direction
;
2794 gFunctionNineString
= Context
->FunctionNineString
;
2795 gFunctionTenString
= Context
->FunctionTenString
;
2796 gEnterString
= Context
->EnterString
;
2797 gEnterCommitString
= Context
->EnterCommitString
;
2798 gEnterEscapeString
= Context
->EnterEscapeString
;
2799 gEscapeString
= Context
->EscapeString
;
2800 gSaveFailed
= Context
->SaveFailed
;
2801 gMoveHighlight
= Context
->MoveHighlight
;
2802 gMakeSelection
= Context
->MakeSelection
;
2803 gDecNumericInput
= Context
->DecNumericInput
;
2804 gHexNumericInput
= Context
->HexNumericInput
;
2805 gToggleCheckBox
= Context
->ToggleCheckBox
;
2806 gPromptForData
= Context
->PromptForData
;
2807 gPromptForPassword
= Context
->PromptForPassword
;
2808 gPromptForNewPassword
= Context
->PromptForNewPassword
;
2809 gConfirmPassword
= Context
->ConfirmPassword
;
2810 gConfirmError
= Context
->ConfirmError
;
2811 gPassowordInvalid
= Context
->PassowordInvalid
;
2812 gPressEnter
= Context
->PressEnter
;
2813 gEmptyString
= Context
->EmptyString
;
2814 gAreYouSure
= Context
->AreYouSure
;
2815 gYesResponse
= Context
->YesResponse
;
2816 gNoResponse
= Context
->NoResponse
;
2817 gMiniString
= Context
->MiniString
;
2818 gPlusString
= Context
->PlusString
;
2819 gMinusString
= Context
->MinusString
;
2820 gAdjustNumber
= Context
->AdjustNumber
;
2821 gSaveChanges
= Context
->SaveChanges
;
2822 gOptionMismatch
= Context
->OptionMismatch
;
2823 gFormSuppress
= Context
->FormSuppress
;
2824 gPromptBlockWidth
= Context
->PromptBlockWidth
;
2825 gOptionBlockWidth
= Context
->OptionBlockWidth
;
2826 gHelpBlockWidth
= Context
->HelpBlockWidth
;
2827 gOldFormSet
= Context
->OldFormSet
;
2828 gMenuRefreshHead
= Context
->MenuRefreshHead
;
2830 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
2831 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
2834 // Remove from FormBrowser context list
2836 RemoveEntryList (&Context
->Link
);
2837 gBS
->FreePool (Context
);