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 EFI_HII_HANDLE gHiiHandle
;
40 EFI_SCREEN_DESCRIPTOR gScreenDimensions
;
43 // Browser Global Strings
45 CHAR16
*gFunctionNineString
;
46 CHAR16
*gFunctionTenString
;
48 CHAR16
*gEnterCommitString
;
49 CHAR16
*gEnterEscapeString
;
50 CHAR16
*gEscapeString
;
52 CHAR16
*gMoveHighlight
;
53 CHAR16
*gMakeSelection
;
54 CHAR16
*gDecNumericInput
;
55 CHAR16
*gHexNumericInput
;
56 CHAR16
*gToggleCheckBox
;
57 CHAR16
*gPromptForData
;
58 CHAR16
*gPromptForPassword
;
59 CHAR16
*gPromptForNewPassword
;
60 CHAR16
*gConfirmPassword
;
61 CHAR16
*gConfirmError
;
62 CHAR16
*gPassowordInvalid
;
71 CHAR16
*gAdjustNumber
;
73 CHAR16
*gOptionMismatch
;
74 CHAR16
*gFormSuppress
;
76 CHAR16
*mUnknownString
= L
"!";
78 CHAR16 gPromptBlockWidth
;
79 CHAR16 gOptionBlockWidth
;
80 CHAR16 gHelpBlockWidth
;
82 EFI_GUID gZeroGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
83 EFI_GUID gSetupBrowserGuid
= {
84 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
87 FORM_BROWSER_FORMSET
*gOldFormSet
;
89 FUNCTIION_KEY_SETTING gFunctionKeySettingTable
[] = {
109 NONE_FUNCTION_KEY_SETTING
130 NONE_FUNCTION_KEY_SETTING
151 NONE_FUNCTION_KEY_SETTING
154 // BMM File Explorer FormSet.
172 NONE_FUNCTION_KEY_SETTING
177 This is the routine which an external caller uses to direct the browser
178 where to obtain it's information.
181 @param This The Form Browser protocol instanse.
182 @param Handles A pointer to an array of Handles. If HandleCount > 1 we
183 display a list of the formsets for the handles specified.
184 @param HandleCount The number of Handles specified in Handle.
185 @param FormSetGuid This field points to the EFI_GUID which must match the Guid
186 field in the EFI_IFR_FORM_SET op-code for the specified
187 forms-based package. If FormSetGuid is NULL, then this
188 function will display the first found forms package.
189 @param FormId This field specifies which EFI_IFR_FORM to render as the first
190 displayable page. If this field has a value of 0x0000, then
191 the forms browser will render the specified forms in their encoded order.
192 @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in
194 @param ActionRequest Points to the action recommended by the form.
196 @retval EFI_SUCCESS The function completed successfully.
197 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
198 @retval EFI_NOT_FOUND No valid forms could be found to display.
204 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
205 IN EFI_HII_HANDLE
*Handles
,
206 IN UINTN HandleCount
,
207 IN EFI_GUID
*FormSetGuid
, OPTIONAL
208 IN UINT16 FormId
, OPTIONAL
209 IN CONST EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
210 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest OPTIONAL
214 UI_MENU_SELECTION
*Selection
;
216 FORM_BROWSER_FORMSET
*FormSet
;
219 // Save globals used by SendForm()
221 SaveBrowserContext ();
223 Status
= EFI_SUCCESS
;
224 ZeroMem (&gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
227 // Seed the dimensions in the global
229 gST
->ConOut
->QueryMode (
231 gST
->ConOut
->Mode
->Mode
,
232 &gScreenDimensions
.RightColumn
,
233 &gScreenDimensions
.BottomRow
236 if (ScreenDimensions
!= NULL
) {
238 // Check local dimension vs. global dimension.
240 if ((gScreenDimensions
.RightColumn
< ScreenDimensions
->RightColumn
) ||
241 (gScreenDimensions
.BottomRow
< ScreenDimensions
->BottomRow
)
243 Status
= EFI_INVALID_PARAMETER
;
247 // Local dimension validation.
249 if ((ScreenDimensions
->RightColumn
> ScreenDimensions
->LeftColumn
) &&
250 (ScreenDimensions
->BottomRow
> ScreenDimensions
->TopRow
) &&
251 ((ScreenDimensions
->RightColumn
- ScreenDimensions
->LeftColumn
) > 2) &&
253 (ScreenDimensions
->BottomRow
- ScreenDimensions
->TopRow
) > STATUS_BAR_HEIGHT
+
254 SCROLL_ARROW_HEIGHT
*
256 FRONT_PAGE_HEADER_HEIGHT
+
261 CopyMem (&gScreenDimensions
, (VOID
*) ScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
263 Status
= EFI_INVALID_PARAMETER
;
269 gOptionBlockWidth
= (CHAR16
) ((gScreenDimensions
.RightColumn
- gScreenDimensions
.LeftColumn
) / 3);
270 gPromptBlockWidth
= (CHAR16
) (gOptionBlockWidth
+ LEFT_SKIPPED_COLUMNS
);
271 gHelpBlockWidth
= (CHAR16
) (gOptionBlockWidth
- LEFT_SKIPPED_COLUMNS
);
274 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
276 InitializeBrowserStrings ();
278 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
281 // Ensure we are in Text mode
283 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
285 for (Index
= 0; Index
< HandleCount
; Index
++) {
286 Selection
= AllocateZeroPool (sizeof (UI_MENU_SELECTION
));
287 ASSERT (Selection
!= NULL
);
289 Selection
->Handle
= Handles
[Index
];
290 if (FormSetGuid
!= NULL
) {
291 CopyMem (&Selection
->FormSetGuid
, FormSetGuid
, sizeof (EFI_GUID
));
292 Selection
->FormId
= FormId
;
298 FormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
299 ASSERT (FormSet
!= NULL
);
302 // Initialize internal data structures of FormSet
304 Status
= InitializeFormSet (Selection
->Handle
, &Selection
->FormSetGuid
, FormSet
);
305 if (EFI_ERROR (Status
) || IsListEmpty (&FormSet
->FormListHead
)) {
306 DestroyFormSet (FormSet
);
309 Selection
->FormSet
= FormSet
;
312 // Display this formset
314 gCurrentSelection
= Selection
;
316 Status
= SetupBrowser (Selection
);
318 gCurrentSelection
= NULL
;
320 if (EFI_ERROR (Status
)) {
324 } while (Selection
->Action
== UI_ACTION_REFRESH_FORMSET
);
326 if (gOldFormSet
!= NULL
) {
327 DestroyFormSet (gOldFormSet
);
331 FreePool (Selection
);
334 if (ActionRequest
!= NULL
) {
335 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
336 if (gResetRequired
) {
337 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
341 FreeBrowserStrings ();
343 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
344 gST
->ConOut
->ClearScreen (gST
->ConOut
);
348 // Restore globals used by SendForm()
350 RestoreBrowserContext ();
357 This function is called by a callback handler to retrieve uncommitted state
358 data from the browser.
360 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
362 @param ResultsDataSize A pointer to the size of the buffer associated
364 @param ResultsData A string returned from an IFR browser or
365 equivalent. The results string will have no
366 routing information in them.
367 @param RetrieveData A BOOLEAN field which allows an agent to retrieve
368 (if RetrieveData = TRUE) data from the uncommitted
369 browser state information or set (if RetrieveData
370 = FALSE) data in the uncommitted browser state
372 @param VariableGuid An optional field to indicate the target variable
374 @param VariableName An optional field to indicate the target
375 human-readable variable name.
377 @retval EFI_SUCCESS The results have been distributed or are awaiting
379 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to
380 contain the results data.
386 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
387 IN OUT UINTN
*ResultsDataSize
,
388 IN OUT EFI_STRING ResultsData
,
389 IN BOOLEAN RetrieveData
,
390 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
391 IN CONST CHAR16
*VariableName OPTIONAL
396 FORMSET_STORAGE
*Storage
;
397 FORM_BROWSER_FORMSET
*FormSet
;
404 if (ResultsDataSize
== NULL
|| ResultsData
== NULL
) {
405 return EFI_INVALID_PARAMETER
;
408 if (gCurrentSelection
== NULL
) {
409 return EFI_NOT_READY
;
414 FormSet
= gCurrentSelection
->FormSet
;
417 // Find target storage
419 Link
= GetFirstNode (&FormSet
->StorageListHead
);
420 if (IsNull (&FormSet
->StorageListHead
, Link
)) {
421 return EFI_UNSUPPORTED
;
424 if (VariableGuid
!= NULL
) {
426 // Try to find target storage
429 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
430 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
431 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
433 if (CompareGuid (&Storage
->Guid
, (EFI_GUID
*) VariableGuid
)) {
434 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
435 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
437 // Buffer storage require both GUID and Name
439 if (VariableName
== NULL
) {
440 return EFI_NOT_FOUND
;
443 if (StrCmp (Storage
->Name
, (CHAR16
*) VariableName
) != 0) {
453 return EFI_NOT_FOUND
;
457 // GUID/Name is not specified, take the first storage in FormSet
459 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
464 // Skip if there is no RequestElement
466 if (Storage
->ElementCount
== 0) {
471 // Generate <ConfigResp>
473 Status
= StorageToConfigResp (Storage
, &ConfigResp
, FALSE
);
474 if (EFI_ERROR (Status
)) {
479 // Skip <ConfigHdr> and '&' to point to <ConfigBody>
481 StrPtr
= ConfigResp
+ StrLen (Storage
->ConfigHdr
) + 1;
483 BufferSize
= StrSize (StrPtr
);
484 if (*ResultsDataSize
< BufferSize
) {
485 *ResultsDataSize
= BufferSize
;
487 FreePool (ConfigResp
);
488 return EFI_BUFFER_TOO_SMALL
;
491 *ResultsDataSize
= BufferSize
;
492 CopyMem (ResultsData
, StrPtr
, BufferSize
);
494 FreePool (ConfigResp
);
497 // Prepare <ConfigResp>
499 TmpSize
= StrLen (ResultsData
);
500 BufferSize
= (TmpSize
+ StrLen (Storage
->ConfigHdr
) + 2) * sizeof (CHAR16
);
501 ConfigResp
= AllocateZeroPool (BufferSize
);
502 ASSERT (ConfigResp
!= NULL
);
504 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
505 StrCat (ConfigResp
, L
"&");
506 StrCat (ConfigResp
, ResultsData
);
509 // Update Browser uncommited data
511 Status
= ConfigRespToStorage (Storage
, ConfigResp
);
512 if (EFI_ERROR (Status
)) {
522 Initialize Setup Browser driver.
524 @param ImageHandle The image handle.
525 @param SystemTable The system table.
527 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
528 @return Other value if failed to initialize the Setup Browser module.
534 IN EFI_HANDLE ImageHandle
,
535 IN EFI_SYSTEM_TABLE
*SystemTable
541 // Locate required Hii relative protocols
543 Status
= gBS
->LocateProtocol (
544 &gEfiHiiDatabaseProtocolGuid
,
546 (VOID
**) &mHiiDatabase
548 ASSERT_EFI_ERROR (Status
);
550 Status
= gBS
->LocateProtocol (
551 &gEfiHiiStringProtocolGuid
,
553 (VOID
**) &mHiiString
555 ASSERT_EFI_ERROR (Status
);
557 Status
= gBS
->LocateProtocol (
558 &gEfiHiiConfigRoutingProtocolGuid
,
560 (VOID
**) &mHiiConfigRouting
562 ASSERT_EFI_ERROR (Status
);
565 // Publish our HII data
567 gHiiHandle
= HiiAddPackages (
573 ASSERT (gHiiHandle
!= NULL
);
576 // Initialize Driver private data
578 gBannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
579 ASSERT (gBannerData
!= NULL
);
582 // Install FormBrowser2 protocol
584 mPrivateData
.Handle
= NULL
;
585 Status
= gBS
->InstallProtocolInterface (
586 &mPrivateData
.Handle
,
587 &gEfiFormBrowser2ProtocolGuid
,
588 EFI_NATIVE_INTERFACE
,
589 &mPrivateData
.FormBrowser2
591 ASSERT_EFI_ERROR (Status
);
598 Create a new string in HII Package List.
600 @param String The String to be added
601 @param HiiHandle The package list in the HII database to insert the
604 @return The output string.
610 IN EFI_HII_HANDLE HiiHandle
613 EFI_STRING_ID StringId
;
615 StringId
= HiiSetString (HiiHandle
, 0, String
, NULL
);
616 ASSERT (StringId
!= 0);
623 Delete a string from HII Package List.
625 @param StringId Id of the string in HII database.
626 @param HiiHandle The HII package list handle.
628 @retval EFI_SUCCESS The string was deleted successfully.
633 IN EFI_STRING_ID StringId
,
634 IN EFI_HII_HANDLE HiiHandle
639 NullChar
= CHAR_NULL
;
640 HiiSetString (HiiHandle
, StringId
, &NullChar
, NULL
);
646 Get the string based on the StringId and HII Package List Handle.
648 @param Token The String's ID.
649 @param HiiHandle The package list in the HII database to search for
650 the specified string.
652 @return The output string.
657 IN EFI_STRING_ID Token
,
658 IN EFI_HII_HANDLE HiiHandle
663 if (HiiHandle
== NULL
) {
667 String
= HiiGetString (HiiHandle
, Token
, NULL
);
668 if (String
== NULL
) {
669 String
= AllocateCopyPool (sizeof (mUnknownString
), mUnknownString
);
670 ASSERT (String
!= NULL
);
672 return (CHAR16
*) String
;
677 Allocate new memory and then copy the Unicode string Source to Destination.
679 @param Dest Location to copy string
680 @param Src String to copy
685 IN OUT CHAR16
**Dest
,
692 *Dest
= AllocateCopyPool (StrSize (Src
), Src
);
693 ASSERT (*Dest
!= NULL
);
698 Allocate new memory and concatinate Source on the end of Destination.
700 @param Dest String to added to the end of.
701 @param Src String to concatinate.
706 IN OUT CHAR16
**Dest
,
714 NewStringCpy (Dest
, Src
);
718 TmpSize
= StrSize (*Dest
);
719 NewString
= AllocateZeroPool (TmpSize
+ StrSize (Src
) - 1);
720 ASSERT (NewString
!= NULL
);
722 StrCpy (NewString
, *Dest
);
723 StrCat (NewString
, Src
);
731 Synchronize or restore Storage's Edit copy and Shadow copy.
733 @param Storage The Storage to be synchronized.
734 @param SyncOrRestore Sync the buffer to editbuffer or Restore the
736 if TRUE, copy the editbuffer to the buffer.
737 if FALSE, copy the buffer to the editbuffer.
742 IN FORMSET_STORAGE
*Storage
,
743 IN BOOLEAN SyncOrRestore
747 NAME_VALUE_NODE
*Node
;
749 switch (Storage
->Type
) {
750 case EFI_HII_VARSTORE_BUFFER
:
751 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
753 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
755 CopyMem (Storage
->EditBuffer
, Storage
->Buffer
, Storage
->Size
);
759 case EFI_HII_VARSTORE_NAME_VALUE
:
760 Link
= GetFirstNode (&Storage
->NameValueListHead
);
761 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
762 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
765 NewStringCpy (&Node
->Value
, Node
->EditValue
);
767 NewStringCpy (&Node
->EditValue
, Node
->Value
);
770 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
774 case EFI_HII_VARSTORE_EFI_VARIABLE
:
782 Get Value for given Name from a NameValue Storage.
784 @param Storage The NameValue Storage.
785 @param Name The Name.
786 @param Value The retured Value.
788 @retval EFI_SUCCESS Value found for given Name.
789 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
794 IN FORMSET_STORAGE
*Storage
,
796 IN OUT CHAR16
**Value
800 NAME_VALUE_NODE
*Node
;
804 Link
= GetFirstNode (&Storage
->NameValueListHead
);
805 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
806 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
808 if (StrCmp (Name
, Node
->Name
) == 0) {
809 NewStringCpy (Value
, Node
->EditValue
);
813 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
816 return EFI_NOT_FOUND
;
821 Set Value of given Name in a NameValue Storage.
823 @param Storage The NameValue Storage.
824 @param Name The Name.
825 @param Value The Value to set.
826 @param Edit Whether update editValue or Value.
828 @retval EFI_SUCCESS Value found for given Name.
829 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
834 IN FORMSET_STORAGE
*Storage
,
841 NAME_VALUE_NODE
*Node
;
844 Link
= GetFirstNode (&Storage
->NameValueListHead
);
845 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
846 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
848 if (StrCmp (Name
, Node
->Name
) == 0) {
850 Buffer
= Node
->EditValue
;
852 Buffer
= Node
->Value
;
854 if (Buffer
!= NULL
) {
857 Buffer
= AllocateCopyPool (StrSize (Value
), Value
);
858 ASSERT (Buffer
!= NULL
);
860 Node
->EditValue
= Buffer
;
862 Node
->Value
= Buffer
;
867 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
870 return EFI_NOT_FOUND
;
875 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
877 @param Buffer The Storage to be conveted.
878 @param ConfigResp The returned <ConfigResp>.
879 @param SingleForm Whether update data for single form or formset level.
881 @retval EFI_SUCCESS Convert success.
882 @retval EFI_INVALID_PARAMETER Incorrect storage type.
886 StorageToConfigResp (
888 IN CHAR16
**ConfigResp
,
889 IN BOOLEAN SingleForm
895 NAME_VALUE_NODE
*Node
;
896 CHAR16
*ConfigRequest
;
897 FORMSET_STORAGE
*Storage
;
898 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
900 Status
= EFI_SUCCESS
;
902 ConfigInfo
= (FORM_BROWSER_CONFIG_REQUEST
*) Buffer
;
903 Storage
= ConfigInfo
->Storage
;
904 ConfigRequest
= ConfigInfo
->ConfigRequest
;
906 Storage
= (FORMSET_STORAGE
*) Buffer
;
907 ConfigRequest
= Storage
->ConfigRequest
;
910 switch (Storage
->Type
) {
911 case EFI_HII_VARSTORE_BUFFER
:
912 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
913 Status
= mHiiConfigRouting
->BlockToConfig (
923 case EFI_HII_VARSTORE_NAME_VALUE
:
925 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
927 Link
= GetFirstNode (&Storage
->NameValueListHead
);
928 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
929 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
931 if (StrStr (ConfigRequest
, Node
->Name
) != NULL
) {
932 NewStringCat (ConfigResp
, L
"&");
933 NewStringCat (ConfigResp
, Node
->Name
);
934 NewStringCat (ConfigResp
, L
"=");
935 NewStringCat (ConfigResp
, Node
->EditValue
);
937 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
941 case EFI_HII_VARSTORE_EFI_VARIABLE
:
943 Status
= EFI_INVALID_PARAMETER
;
952 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
954 @param Storage The Storage to receive the settings.
955 @param ConfigResp The <ConfigResp> to be converted.
957 @retval EFI_SUCCESS Convert success.
958 @retval EFI_INVALID_PARAMETER Incorrect storage type.
962 ConfigRespToStorage (
963 IN FORMSET_STORAGE
*Storage
,
964 IN CHAR16
*ConfigResp
974 Status
= EFI_SUCCESS
;
976 switch (Storage
->Type
) {
977 case EFI_HII_VARSTORE_BUFFER
:
978 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
979 BufferSize
= Storage
->Size
;
980 Status
= mHiiConfigRouting
->ConfigToBlock (
989 case EFI_HII_VARSTORE_NAME_VALUE
:
990 StrPtr
= StrStr (ConfigResp
, L
"PATH");
991 if (StrPtr
== NULL
) {
994 StrPtr
= StrStr (ConfigResp
, L
"&");
995 while (StrPtr
!= NULL
) {
1001 StrPtr
= StrStr (StrPtr
, L
"=");
1002 if (StrPtr
== NULL
) {
1010 StrPtr
= StrPtr
+ 1;
1012 StrPtr
= StrStr (StrPtr
, L
"&");
1013 if (StrPtr
!= NULL
) {
1016 SetValueByName (Storage
, Name
, Value
, TRUE
);
1020 case EFI_HII_VARSTORE_EFI_VARIABLE
:
1022 Status
= EFI_INVALID_PARAMETER
;
1031 Get Question's current Value.
1033 @param FormSet FormSet data structure.
1034 @param Form Form data structure.
1035 @param Question Question to be initialized.
1036 @param Cached TRUE: get from Edit copy FALSE: get from original
1039 @retval EFI_SUCCESS The function completed successfully.
1044 IN FORM_BROWSER_FORMSET
*FormSet
,
1045 IN FORM_BROWSER_FORM
*Form
,
1046 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1056 FORMSET_STORAGE
*Storage
;
1057 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1058 CHAR16
*ConfigRequest
;
1066 BOOLEAN IsBufferStorage
;
1072 Status
= EFI_SUCCESS
;
1076 // Statement don't have storage, skip them
1078 if (Question
->QuestionId
== 0) {
1083 // Question value is provided by an Expression, evaluate it
1085 if (Question
->ValueExpression
!= NULL
) {
1086 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1087 if (!EFI_ERROR (Status
)) {
1088 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1094 // Get question value by read expression.
1096 if (Question
->ReadExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1097 Status
= EvaluateExpression (FormSet
, Form
, Question
->ReadExpression
);
1098 if (!EFI_ERROR (Status
) && (Question
->ReadExpression
->Result
.Type
< EFI_IFR_TYPE_OTHER
)) {
1100 // Only update question value to the valid result.
1102 CopyMem (&Question
->HiiValue
, &Question
->ReadExpression
->Result
, sizeof (EFI_HII_VALUE
));
1108 // Question value is provided by RTC
1110 Storage
= Question
->Storage
;
1111 QuestionValue
= &Question
->HiiValue
.Value
;
1112 if (Storage
== NULL
) {
1114 // It's a Question without storage, or RTC date/time
1116 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1118 // Date and time define the same Flags bit
1120 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1121 case QF_DATE_STORAGE_TIME
:
1122 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1125 case QF_DATE_STORAGE_WAKEUP
:
1126 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1129 case QF_DATE_STORAGE_NORMAL
:
1132 // For date/time without storage
1137 if (EFI_ERROR (Status
)) {
1141 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1142 QuestionValue
->date
.Year
= EfiTime
.Year
;
1143 QuestionValue
->date
.Month
= EfiTime
.Month
;
1144 QuestionValue
->date
.Day
= EfiTime
.Day
;
1146 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1147 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1148 QuestionValue
->time
.Second
= EfiTime
.Second
;
1156 // Question value is provided by EFI variable
1158 StorageWidth
= Question
->StorageWidth
;
1159 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1160 if (Question
->BufferValue
!= NULL
) {
1161 Dst
= Question
->BufferValue
;
1163 Dst
= (UINT8
*) QuestionValue
;
1166 Status
= gRT
->GetVariable (
1167 Question
->VariableName
,
1174 // Always return success, even this EFI variable doesn't exist
1180 // Question Value is provided by Buffer Storage or NameValue Storage
1182 if (Question
->BufferValue
!= NULL
) {
1184 // This Question is password or orderedlist
1186 Dst
= Question
->BufferValue
;
1189 // Other type of Questions
1191 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1194 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
1195 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1196 IsBufferStorage
= TRUE
;
1198 IsBufferStorage
= FALSE
;
1200 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1202 if (IsBufferStorage
) {
1204 // Copy from storage Edit buffer
1206 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1209 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1210 if (EFI_ERROR (Status
)) {
1214 ASSERT (Value
!= NULL
);
1215 LengthStr
= StrLen (Value
);
1216 Status
= EFI_SUCCESS
;
1219 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1220 // Add string tail char L'\0' into Length
1222 Length
= StorageWidth
+ sizeof (CHAR16
);
1223 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1224 Status
= EFI_BUFFER_TOO_SMALL
;
1226 StringPtr
= (CHAR16
*) Dst
;
1227 ZeroMem (TemStr
, sizeof (TemStr
));
1228 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1229 StrnCpy (TemStr
, Value
+ Index
, 4);
1230 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1233 // Add tailing L'\0' character
1235 StringPtr
[Index
/4] = L
'\0';
1238 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1239 Status
= EFI_BUFFER_TOO_SMALL
;
1241 ZeroMem (TemStr
, sizeof (TemStr
));
1242 for (Index
= 0; Index
< LengthStr
; Index
++) {
1243 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1244 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1245 if ((Index
& 1) == 0) {
1246 Dst
[Index
/2] = DigitUint8
;
1248 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1257 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
1259 // Request current settings from Configuration Driver
1261 if (FormSet
->ConfigAccess
== NULL
) {
1262 return EFI_NOT_FOUND
;
1266 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1267 // <ConfigHdr> + "&" + <VariableName>
1269 if (IsBufferStorage
) {
1270 Length
= StrLen (Storage
->ConfigHdr
);
1271 Length
+= StrLen (Question
->BlockName
);
1273 Length
= StrLen (Storage
->ConfigHdr
);
1274 Length
+= StrLen (Question
->VariableName
) + 1;
1276 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1277 ASSERT (ConfigRequest
!= NULL
);
1279 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1280 if (IsBufferStorage
) {
1281 StrCat (ConfigRequest
, Question
->BlockName
);
1283 StrCat (ConfigRequest
, L
"&");
1284 StrCat (ConfigRequest
, Question
->VariableName
);
1287 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1288 FormSet
->ConfigAccess
,
1293 FreePool (ConfigRequest
);
1294 if (EFI_ERROR (Status
)) {
1299 // Skip <ConfigRequest>
1301 Value
= Result
+ Length
;
1302 if (IsBufferStorage
) {
1308 if (*Value
!= '=') {
1310 return EFI_NOT_FOUND
;
1313 // Skip '=', point to value
1318 // Suppress <AltResp> if any
1321 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1326 LengthStr
= StrLen (Value
);
1327 Status
= EFI_SUCCESS
;
1328 if (!IsBufferStorage
&& IsString
) {
1330 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1331 // Add string tail char L'\0' into Length
1333 Length
= StorageWidth
+ sizeof (CHAR16
);
1334 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1335 Status
= EFI_BUFFER_TOO_SMALL
;
1337 StringPtr
= (CHAR16
*) Dst
;
1338 ZeroMem (TemStr
, sizeof (TemStr
));
1339 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1340 StrnCpy (TemStr
, Value
+ Index
, 4);
1341 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1344 // Add tailing L'\0' character
1346 StringPtr
[Index
/4] = L
'\0';
1349 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1350 Status
= EFI_BUFFER_TOO_SMALL
;
1352 ZeroMem (TemStr
, sizeof (TemStr
));
1353 for (Index
= 0; Index
< LengthStr
; Index
++) {
1354 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1355 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1356 if ((Index
& 1) == 0) {
1357 Dst
[Index
/2] = DigitUint8
;
1359 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1366 if (EFI_ERROR (Status
)) {
1369 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1371 TemBuffer
= AllocateZeroPool (Storage
->Size
);
1372 if (TemBuffer
== NULL
) {
1373 Status
= EFI_OUT_OF_RESOURCES
;
1376 Length
= Storage
->Size
;
1377 Status
= gRT
->GetVariable (
1384 if (EFI_ERROR (Status
)) {
1385 FreePool (TemBuffer
);
1389 CopyMem (Dst
, TemBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1391 FreePool (TemBuffer
);
1395 // Synchronize Edit Buffer
1397 if (IsBufferStorage
) {
1398 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1400 SetValueByName (Storage
, Question
->VariableName
, Value
, TRUE
);
1409 Save Question Value to edit copy(cached) or Storage(uncached).
1411 @param FormSet FormSet data structure.
1412 @param Form Form data structure.
1413 @param Question Pointer to the Question.
1414 @param Cached TRUE: set to Edit copy FALSE: set to original
1417 @retval EFI_SUCCESS The function completed successfully.
1422 IN FORM_BROWSER_FORMSET
*FormSet
,
1423 IN FORM_BROWSER_FORM
*Form
,
1424 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1435 FORMSET_STORAGE
*Storage
;
1436 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1441 BOOLEAN IsBufferStorage
;
1448 Status
= EFI_SUCCESS
;
1451 // Statement don't have storage, skip them
1453 if (Question
->QuestionId
== 0) {
1458 // If Question value is provided by an Expression, then it is read only
1460 if (Question
->ValueExpression
!= NULL
) {
1465 // Before set question value, evaluate its write expression.
1467 if (Question
->WriteExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1468 Status
= EvaluateExpression (FormSet
, Form
, Question
->WriteExpression
);
1469 if (EFI_ERROR (Status
)) {
1475 // Question value is provided by RTC
1477 Storage
= Question
->Storage
;
1478 QuestionValue
= &Question
->HiiValue
.Value
;
1479 if (Storage
== NULL
) {
1481 // It's a Question without storage, or RTC date/time
1483 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1485 // Date and time define the same Flags bit
1487 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1488 case QF_DATE_STORAGE_TIME
:
1489 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1492 case QF_DATE_STORAGE_WAKEUP
:
1493 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1496 case QF_DATE_STORAGE_NORMAL
:
1499 // For date/time without storage
1504 if (EFI_ERROR (Status
)) {
1508 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1509 EfiTime
.Year
= QuestionValue
->date
.Year
;
1510 EfiTime
.Month
= QuestionValue
->date
.Month
;
1511 EfiTime
.Day
= QuestionValue
->date
.Day
;
1513 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1514 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1515 EfiTime
.Second
= QuestionValue
->time
.Second
;
1518 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1519 Status
= gRT
->SetTime (&EfiTime
);
1521 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1529 // Question value is provided by EFI variable
1531 StorageWidth
= Question
->StorageWidth
;
1532 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1533 if (Question
->BufferValue
!= NULL
) {
1534 Src
= Question
->BufferValue
;
1536 Src
= (UINT8
*) QuestionValue
;
1539 Status
= gRT
->SetVariable (
1540 Question
->VariableName
,
1542 Storage
->Attributes
,
1550 // Question Value is provided by Buffer Storage or NameValue Storage
1552 if (Question
->BufferValue
!= NULL
) {
1553 Src
= Question
->BufferValue
;
1555 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1558 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
1559 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1560 IsBufferStorage
= TRUE
;
1562 IsBufferStorage
= FALSE
;
1564 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1565 if (IsBufferStorage
) {
1567 // Copy to storage edit buffer
1569 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1573 // Allocate enough string buffer.
1576 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1577 Value
= AllocateZeroPool (BufferLen
);
1578 ASSERT (Value
!= NULL
);
1580 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1582 TemName
= (CHAR16
*) Src
;
1584 for (; *TemName
!= L
'\0'; TemName
++) {
1585 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1588 BufferLen
= StorageWidth
* 2 + 1;
1589 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1590 ASSERT (Value
!= NULL
);
1592 // Convert Buffer to Hex String
1594 TemBuffer
= Src
+ StorageWidth
- 1;
1596 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1597 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1601 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
, TRUE
);
1606 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
1608 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1609 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1611 if (IsBufferStorage
) {
1612 Length
= StrLen (Question
->BlockName
) + 7;
1614 Length
= StrLen (Question
->VariableName
) + 2;
1616 if (!IsBufferStorage
&& IsString
) {
1617 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1619 Length
+= (StorageWidth
* 2);
1621 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1622 ASSERT (ConfigResp
!= NULL
);
1624 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1625 if (IsBufferStorage
) {
1626 StrCat (ConfigResp
, Question
->BlockName
);
1627 StrCat (ConfigResp
, L
"&VALUE=");
1629 StrCat (ConfigResp
, L
"&");
1630 StrCat (ConfigResp
, Question
->VariableName
);
1631 StrCat (ConfigResp
, L
"=");
1634 Value
= ConfigResp
+ StrLen (ConfigResp
);
1636 if (!IsBufferStorage
&& IsString
) {
1638 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1640 TemName
= (CHAR16
*) Src
;
1642 for (; *TemName
!= L
'\0'; TemName
++) {
1643 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1647 // Convert Buffer to Hex String
1649 TemBuffer
= Src
+ StorageWidth
- 1;
1651 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1652 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1657 // Convert to lower char.
1659 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1660 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1661 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1666 // Submit Question Value to Configuration Driver
1668 if (FormSet
->ConfigAccess
!= NULL
) {
1669 Status
= FormSet
->ConfigAccess
->RouteConfig (
1670 FormSet
->ConfigAccess
,
1674 if (EFI_ERROR (Status
)) {
1675 FreePool (ConfigResp
);
1679 FreePool (ConfigResp
);
1681 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1683 TemBuffer
= AllocateZeroPool(Storage
->Size
);
1684 if (TemBuffer
== NULL
) {
1685 Status
= EFI_OUT_OF_RESOURCES
;
1688 Length
= Storage
->Size
;
1689 Status
= gRT
->GetVariable (
1697 CopyMem (TemBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1699 Status
= gRT
->SetVariable (
1702 Storage
->Attributes
,
1706 FreePool (TemBuffer
);
1707 if (EFI_ERROR (Status
)){
1712 // Sync storage, from editbuffer to buffer.
1714 CopyMem (Storage
->Buffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1722 Perform inconsistent check for a Form.
1724 @param FormSet FormSet data structure.
1725 @param Form Form data structure.
1726 @param Question The Question to be validated.
1727 @param Type Validation type: InConsistent or NoSubmit
1729 @retval EFI_SUCCESS Form validation pass.
1730 @retval other Form validation failed.
1735 IN FORM_BROWSER_FORMSET
*FormSet
,
1736 IN FORM_BROWSER_FORM
*Form
,
1737 IN FORM_BROWSER_STATEMENT
*Question
,
1743 LIST_ENTRY
*ListHead
;
1746 FORM_EXPRESSION
*Expression
;
1748 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1749 ListHead
= &Question
->InconsistentListHead
;
1750 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1751 ListHead
= &Question
->NoSubmitListHead
;
1753 return EFI_UNSUPPORTED
;
1756 Link
= GetFirstNode (ListHead
);
1757 while (!IsNull (ListHead
, Link
)) {
1758 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1761 // Evaluate the expression
1763 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1764 if (EFI_ERROR (Status
)) {
1768 if (Expression
->Result
.Value
.b
) {
1770 // Condition meet, show up error message
1772 if (Expression
->Error
!= 0) {
1773 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1775 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1776 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1780 return EFI_NOT_READY
;
1783 Link
= GetNextNode (ListHead
, Link
);
1791 Perform NoSubmit check for each Form in FormSet.
1793 @param FormSet FormSet data structure.
1794 @param CurrentForm Current input form data structure.
1796 @retval EFI_SUCCESS Form validation pass.
1797 @retval other Form validation failed.
1802 IN FORM_BROWSER_FORMSET
*FormSet
,
1803 IN FORM_BROWSER_FORM
*CurrentForm
1808 FORM_BROWSER_STATEMENT
*Question
;
1809 FORM_BROWSER_FORM
*Form
;
1810 LIST_ENTRY
*LinkForm
;
1812 LinkForm
= GetFirstNode (&FormSet
->FormListHead
);
1813 while (!IsNull (&FormSet
->FormListHead
, LinkForm
)) {
1814 Form
= FORM_BROWSER_FORM_FROM_LINK (LinkForm
);
1815 LinkForm
= GetNextNode (&FormSet
->FormListHead
, LinkForm
);
1817 if (CurrentForm
!= NULL
&& CurrentForm
!= Form
) {
1821 Link
= GetFirstNode (&Form
->StatementListHead
);
1822 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1823 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1825 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1826 if (EFI_ERROR (Status
)) {
1830 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1838 Fill storage's edit copy with settings requested from Configuration Driver.
1840 @param FormSet FormSet data structure.
1841 @param ConfigInfo The config info related to this form.
1842 @param SyncOrRestore Sync the buffer to editbuffer or Restore the
1843 editbuffer to buffer
1844 if TRUE, copy the editbuffer to the buffer.
1845 if FALSE, copy the buffer to the editbuffer.
1847 @retval EFI_SUCCESS The function completed successfully.
1851 SynchronizeStorageForForm (
1852 IN FORM_BROWSER_FORMSET
*FormSet
,
1853 IN FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
,
1854 IN BOOLEAN SyncOrRestore
1858 EFI_STRING Progress
;
1862 NAME_VALUE_NODE
*Node
;
1866 Status
= EFI_SUCCESS
;
1868 if (FormSet
->ConfigAccess
== NULL
&& ConfigInfo
->Storage
->Type
!= EFI_HII_VARSTORE_NAME_VALUE
) {
1869 return EFI_NOT_FOUND
;
1872 if (ConfigInfo
->ElementCount
== 0) {
1874 // Skip if there is no RequestElement
1879 if (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
1880 (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
)) {
1881 BufferSize
= ConfigInfo
->Storage
->Size
;
1883 if (SyncOrRestore
) {
1884 Src
= ConfigInfo
->Storage
->EditBuffer
;
1885 Dst
= ConfigInfo
->Storage
->Buffer
;
1887 Src
= ConfigInfo
->Storage
->Buffer
;
1888 Dst
= ConfigInfo
->Storage
->EditBuffer
;
1891 Status
= mHiiConfigRouting
->BlockToConfig(
1893 ConfigInfo
->ConfigRequest
,
1899 if (EFI_ERROR (Status
)) {
1903 Status
= mHiiConfigRouting
->ConfigToBlock (
1910 if (Result
!= NULL
) {
1913 } else if (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
1914 Link
= GetFirstNode (&ConfigInfo
->Storage
->NameValueListHead
);
1915 while (!IsNull (&ConfigInfo
->Storage
->NameValueListHead
, Link
)) {
1916 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
1918 if (StrStr (ConfigInfo
->ConfigRequest
, Node
->Name
) != NULL
) {
1919 if (SyncOrRestore
) {
1920 NewStringCpy (&Node
->Value
, Node
->EditValue
);
1922 NewStringCpy (&Node
->EditValue
, Node
->Value
);
1926 Link
= GetNextNode (&ConfigInfo
->Storage
->NameValueListHead
, Link
);
1935 Discard data for form level or formset level.
1937 @param FormSet FormSet data structure.
1938 @param Form Form data structure.
1939 @param SingleForm Only discard single form or formset.
1941 @retval EFI_SUCCESS The function completed successfully.
1946 IN FORM_BROWSER_FORMSET
*FormSet
,
1947 IN FORM_BROWSER_FORM
*Form
,
1948 IN BOOLEAN SingleForm
1952 FORMSET_STORAGE
*Storage
;
1953 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
1956 if (Form
->NvUpdateRequired
) {
1958 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
1959 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
1960 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
1961 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
1963 if (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1968 // Skip if there is no RequestElement
1970 if (ConfigInfo
->ElementCount
== 0) {
1975 // Prepare <ConfigResp>
1977 SynchronizeStorageForForm(FormSet
, ConfigInfo
, FALSE
);
1980 Form
->NvUpdateRequired
= FALSE
;
1983 if (IsNvUpdateRequired(FormSet
)) {
1985 // Discard Buffer storage or Name/Value storage
1987 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1988 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1989 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1990 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1992 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1997 // Skip if there is no RequestElement
1999 if (Storage
->ElementCount
== 0) {
2003 SynchronizeStorage(Storage
, FALSE
);
2006 UpdateNvInfoInForm(FormSet
, FALSE
);
2014 Submit data for form level or formset level.
2016 @param FormSet FormSet data structure.
2017 @param Form Form data structure.
2018 @param SingleForm whether submit for the single form or all form set.
2020 @retval EFI_SUCCESS The function completed successfully.
2025 IN FORM_BROWSER_FORMSET
*FormSet
,
2026 IN FORM_BROWSER_FORM
*Form
,
2027 IN BOOLEAN SingleForm
2032 EFI_STRING ConfigResp
;
2033 EFI_STRING Progress
;
2034 FORMSET_STORAGE
*Storage
;
2037 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
2040 // Validate the Form by NoSubmit check
2043 Status
= NoSubmitCheck (FormSet
, Form
);
2045 Status
= NoSubmitCheck (FormSet
, NULL
);
2047 if (EFI_ERROR (Status
)) {
2053 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
2054 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
2055 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
2056 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
2058 Storage
= ConfigInfo
->Storage
;
2059 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2064 // Skip if there is no RequestElement
2066 if (ConfigInfo
->ElementCount
== 0) {
2071 // 1. Prepare <ConfigResp>
2073 Status
= StorageToConfigResp (ConfigInfo
, &ConfigResp
, TRUE
);
2074 if (EFI_ERROR (Status
)) {
2079 // 2. Set value to hii driver or efi variable.
2081 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
2082 Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
2084 // Send <ConfigResp> to Configuration Driver
2086 if (FormSet
->ConfigAccess
!= NULL
) {
2087 Status
= FormSet
->ConfigAccess
->RouteConfig (
2088 FormSet
->ConfigAccess
,
2092 if (EFI_ERROR (Status
)) {
2093 FreePool (ConfigResp
);
2097 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
2099 TmpBuf
= AllocateZeroPool(Storage
->Size
);
2100 if (TmpBuf
== NULL
) {
2101 Status
= EFI_OUT_OF_RESOURCES
;
2105 BufferSize
= Storage
->Size
;
2106 Status
= gRT
->GetVariable (
2113 if (EFI_ERROR (Status
)) {
2115 FreePool (ConfigResp
);
2118 ASSERT (BufferSize
== Storage
->Size
);
2119 Status
= mHiiConfigRouting
->ConfigToBlock (
2126 if (EFI_ERROR (Status
)) {
2128 FreePool (ConfigResp
);
2132 Status
= gRT
->SetVariable (
2135 Storage
->Attributes
,
2140 if (EFI_ERROR (Status
)) {
2141 FreePool (ConfigResp
);
2145 FreePool (ConfigResp
);
2147 // 3. Config success, update storage shadow Buffer, only update the data belong to this form.
2149 SynchronizeStorageForForm(FormSet
, ConfigInfo
, TRUE
);
2153 // 4. Update the NV flag.
2155 Form
->NvUpdateRequired
= FALSE
;
2158 // Submit Buffer storage or Name/Value storage
2160 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2161 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2162 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2163 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2165 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2170 // Skip if there is no RequestElement
2172 if (Storage
->ElementCount
== 0) {
2177 // 1. Prepare <ConfigResp>
2179 Status
= StorageToConfigResp (Storage
, &ConfigResp
, FALSE
);
2180 if (EFI_ERROR (Status
)) {
2184 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
2185 Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
2188 // 2. Send <ConfigResp> to Configuration Driver
2190 if (FormSet
->ConfigAccess
!= NULL
) {
2191 Status
= FormSet
->ConfigAccess
->RouteConfig (
2192 FormSet
->ConfigAccess
,
2196 if (EFI_ERROR (Status
)) {
2197 FreePool (ConfigResp
);
2201 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
2203 // 1&2. Set the edit data to the variable.
2206 TmpBuf
= AllocateZeroPool (Storage
->Size
);
2207 if (TmpBuf
== NULL
) {
2208 Status
= EFI_OUT_OF_RESOURCES
;
2211 BufferSize
= Storage
->Size
;
2212 Status
= gRT
->GetVariable (
2219 ASSERT (BufferSize
== Storage
->Size
);
2220 Status
= mHiiConfigRouting
->ConfigToBlock (
2227 if (EFI_ERROR (Status
)) {
2229 FreePool (ConfigResp
);
2233 Status
= gRT
->SetVariable (
2236 Storage
->Attributes
,
2240 if (EFI_ERROR (Status
)) {
2242 FreePool (ConfigResp
);
2247 FreePool (ConfigResp
);
2249 // 3. Config success, update storage shadow Buffer
2251 SynchronizeStorage (Storage
, TRUE
);
2255 // 4. Update the NV flag.
2257 UpdateNvInfoInForm(FormSet
, FALSE
);
2264 Get Question default value from AltCfg string.
2266 @param FormSet The form set.
2267 @param Question The question.
2268 @param DefaultId The default Id.
2270 @retval EFI_SUCCESS Question is reset to default value.
2274 GetDefaultValueFromAltCfg (
2275 IN FORM_BROWSER_FORMSET
*FormSet
,
2276 IN OUT FORM_BROWSER_STATEMENT
*Question
,
2280 BOOLEAN IsBufferStorage
;
2283 FORMSET_STORAGE
*Storage
;
2284 CHAR16
*ConfigRequest
;
2297 Status
= EFI_NOT_FOUND
;
2300 ConfigRequest
= NULL
;
2304 Storage
= Question
->Storage
;
2306 if ((Storage
== NULL
) ||
2307 (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) ||
2308 (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
)) {
2313 // Question Value is provided by Buffer Storage or NameValue Storage
2315 if (Question
->BufferValue
!= NULL
) {
2317 // This Question is password or orderedlist
2319 Dst
= Question
->BufferValue
;
2322 // Other type of Questions
2324 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
2327 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
2328 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
2331 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
2332 // <ConfigHdr> + "&" + <VariableName>
2334 if (IsBufferStorage
) {
2335 Length
= StrLen (Storage
->ConfigHdr
);
2336 Length
+= StrLen (Question
->BlockName
);
2338 Length
= StrLen (Storage
->ConfigHdr
);
2339 Length
+= StrLen (Question
->VariableName
) + 1;
2341 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
2342 ASSERT (ConfigRequest
!= NULL
);
2344 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
2345 if (IsBufferStorage
) {
2346 StrCat (ConfigRequest
, Question
->BlockName
);
2348 StrCat (ConfigRequest
, L
"&");
2349 StrCat (ConfigRequest
, Question
->VariableName
);
2352 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2353 FormSet
->ConfigAccess
,
2358 if (EFI_ERROR (Status
)) {
2363 // Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)
2364 // Get the default configuration string according to the default ID.
2366 Status
= mHiiConfigRouting
->GetAltConfig (
2372 &DefaultId
, // it can be NULL to get the current setting.
2377 // The required setting can't be found. So, it is not required to be validated and set.
2379 if (EFI_ERROR (Status
)) {
2384 // Skip <ConfigRequest>
2386 if (IsBufferStorage
) {
2387 Value
= StrStr (ConfigResp
, L
"&VALUE");
2388 ASSERT (Value
!= NULL
);
2394 Value
= StrStr (ConfigResp
, Question
->VariableName
);
2395 ASSERT (Value
!= NULL
);
2397 Value
= Value
+ StrLen (Question
->VariableName
);
2399 if (*Value
!= '=') {
2400 Status
= EFI_NOT_FOUND
;
2404 // Skip '=', point to value
2409 // Suppress <AltResp> if any
2412 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
2417 LengthStr
= StrLen (Value
);
2418 if (!IsBufferStorage
&& IsString
) {
2419 StringPtr
= (CHAR16
*) Dst
;
2420 ZeroMem (TemStr
, sizeof (TemStr
));
2421 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
2422 StrnCpy (TemStr
, Value
+ Index
, 4);
2423 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
2426 // Add tailing L'\0' character
2428 StringPtr
[Index
/4] = L
'\0';
2430 ZeroMem (TemStr
, sizeof (TemStr
));
2431 for (Index
= 0; Index
< LengthStr
; Index
++) {
2432 TemStr
[0] = Value
[LengthStr
- Index
- 1];
2433 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
2434 if ((Index
& 1) == 0) {
2435 Dst
[Index
/2] = DigitUint8
;
2437 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
2443 if (ConfigRequest
!= NULL
){
2444 FreePool (ConfigRequest
);
2447 if (ConfigResp
!= NULL
) {
2448 FreePool (ConfigResp
);
2451 if (Result
!= NULL
) {
2459 Get default Id value used for browser.
2461 @param DefaultId The default id value used by hii.
2463 @retval Browser used default value.
2467 GetDefaultIdForCallBack (
2471 if (DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) {
2472 return EFI_BROWSER_ACTION_DEFAULT_STANDARD
;
2473 } else if (DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2474 return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
;
2475 } else if (DefaultId
== EFI_HII_DEFAULT_CLASS_SAFE
) {
2476 return EFI_BROWSER_ACTION_DEFAULT_SAFE
;
2477 } else if (DefaultId
>= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN
&& DefaultId
< EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN
+ 0x1000) {
2478 return EFI_BROWSER_ACTION_DEFAULT_PLATFORM
+ DefaultId
- EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN
;
2479 } else if (DefaultId
>= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN
&& DefaultId
< EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN
+ 0x1000) {
2480 return EFI_BROWSER_ACTION_DEFAULT_HARDWARE
+ DefaultId
- EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN
;
2481 } else if (DefaultId
>= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN
&& DefaultId
< EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN
+ 0x1000) {
2482 return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE
+ DefaultId
- EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN
;
2489 Reset Question to its default value.
2491 @param FormSet The form set.
2492 @param Form The form.
2493 @param Question The question.
2494 @param DefaultId The Class of the default.
2496 @retval EFI_SUCCESS Question is reset to default value.
2500 GetQuestionDefault (
2501 IN FORM_BROWSER_FORMSET
*FormSet
,
2502 IN FORM_BROWSER_FORM
*Form
,
2503 IN FORM_BROWSER_STATEMENT
*Question
,
2509 QUESTION_DEFAULT
*Default
;
2510 QUESTION_OPTION
*Option
;
2511 EFI_HII_VALUE
*HiiValue
;
2513 EFI_STRING StrValue
;
2514 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2515 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2518 Status
= EFI_SUCCESS
;
2522 // Statement don't have storage, skip them
2524 if (Question
->QuestionId
== 0) {
2529 // There are Five ways to specify default value for a Question:
2530 // 1, use call back function (highest priority)
2531 // 2, use ExtractConfig function
2532 // 3, use nested EFI_IFR_DEFAULT
2533 // 4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
2534 // 5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
2536 HiiValue
= &Question
->HiiValue
;
2539 // Get Question defaut value from call back function.
2541 ConfigAccess
= FormSet
->ConfigAccess
;
2542 Action
= GetDefaultIdForCallBack (DefaultId
);
2543 if ((Action
> 0) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) && (ConfigAccess
!= NULL
)) {
2544 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2545 Status
= ConfigAccess
->Callback (
2548 Question
->QuestionId
,
2553 if (!EFI_ERROR (Status
)) {
2559 // Get default value from altcfg string.
2561 if (ConfigAccess
!= NULL
) {
2562 Status
= GetDefaultValueFromAltCfg(FormSet
, Question
, DefaultId
);
2563 if (!EFI_ERROR (Status
)) {
2569 // EFI_IFR_DEFAULT has highest priority
2571 if (!IsListEmpty (&Question
->DefaultListHead
)) {
2572 Link
= GetFirstNode (&Question
->DefaultListHead
);
2573 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
2574 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
2576 if (Default
->DefaultId
== DefaultId
) {
2577 if (Default
->ValueExpression
!= NULL
) {
2579 // Default is provided by an Expression, evaluate it
2581 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
2582 if (EFI_ERROR (Status
)) {
2586 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
2589 // Default value is embedded in EFI_IFR_DEFAULT
2591 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
2594 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2595 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
2596 if (StrValue
== NULL
) {
2597 return EFI_NOT_FOUND
;
2599 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
2605 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
2610 // EFI_ONE_OF_OPTION
2612 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
2613 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2615 // OneOfOption could only provide Standard and Manufacturing default
2617 Link
= GetFirstNode (&Question
->OptionListHead
);
2618 while (!IsNull (&Question
->OptionListHead
, Link
)) {
2619 Option
= QUESTION_OPTION_FROM_LINK (Link
);
2621 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
2622 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
2624 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
2629 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
2635 // EFI_IFR_CHECKBOX - lowest priority
2637 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
2638 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2640 // Checkbox could only provide Standard and Manufacturing default
2642 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
2643 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
2645 HiiValue
->Value
.b
= TRUE
;
2647 HiiValue
->Value
.b
= FALSE
;
2655 // For Questions without default
2657 switch (Question
->Operand
) {
2658 case EFI_IFR_NUMERIC_OP
:
2660 // Take minimum value as numeric default value
2662 if ((HiiValue
->Value
.u64
< Question
->Minimum
) || (HiiValue
->Value
.u64
> Question
->Maximum
)) {
2663 HiiValue
->Value
.u64
= Question
->Minimum
;
2667 case EFI_IFR_ONE_OF_OP
:
2669 // Take first oneof option as oneof's default value
2671 if (ValueToOption (Question
, HiiValue
) == NULL
) {
2672 Link
= GetFirstNode (&Question
->OptionListHead
);
2673 if (!IsNull (&Question
->OptionListHead
, Link
)) {
2674 Option
= QUESTION_OPTION_FROM_LINK (Link
);
2675 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
2680 case EFI_IFR_ORDERED_LIST_OP
:
2682 // Take option sequence in IFR as ordered list's default value
2685 Link
= GetFirstNode (&Question
->OptionListHead
);
2686 while (!IsNull (&Question
->OptionListHead
, Link
)) {
2687 Option
= QUESTION_OPTION_FROM_LINK (Link
);
2689 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
2692 if (Index
>= Question
->MaxContainers
) {
2696 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
2701 Status
= EFI_NOT_FOUND
;
2710 Reset Questions in a Formset to their default value.
2712 @param FormSet FormSet data structure.
2713 @param DefaultId The Class of the default.
2715 @retval EFI_SUCCESS The function completed successfully.
2719 ExtractFormSetDefault (
2720 IN FORM_BROWSER_FORMSET
*FormSet
,
2725 LIST_ENTRY
*FormLink
;
2726 LIST_ENTRY
*StatementLink
;
2727 FORM_BROWSER_STATEMENT
*Question
;
2728 FORM_BROWSER_FORM
*Form
;
2730 FormLink
= GetFirstNode (&FormSet
->FormListHead
);
2731 while (!IsNull (&FormSet
->FormListHead
, FormLink
)) {
2732 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
2735 // Extract Form default
2737 StatementLink
= GetFirstNode (&Form
->StatementListHead
);
2738 while (!IsNull (&Form
->StatementListHead
, StatementLink
)) {
2739 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (StatementLink
);
2740 StatementLink
= GetNextNode (&Form
->StatementListHead
, StatementLink
);
2743 // If Question is disabled, don't reset it to default
2745 if (Question
->DisableExpression
!= NULL
) {
2746 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
2747 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
2753 // Reset Question to its default value
2755 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
2756 if (EFI_ERROR (Status
)) {
2761 // Synchronize Buffer storage's Edit buffer
2763 if ((Question
->Storage
!= NULL
) &&
2764 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
2765 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2768 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
2775 Initialize Question's Edit copy from Storage.
2777 @param Selection Selection contains the information about
2778 the Selection, form and formset to be displayed.
2779 Selection action may be updated in retrieve callback.
2780 @param FormSet FormSet data structure.
2781 @param Form Form data structure.
2783 @retval EFI_SUCCESS The function completed successfully.
2788 IN OUT UI_MENU_SELECTION
*Selection
,
2789 IN FORM_BROWSER_FORMSET
*FormSet
,
2790 IN FORM_BROWSER_FORM
*Form
2795 FORM_BROWSER_STATEMENT
*Question
;
2799 Link
= GetFirstNode (&Form
->StatementListHead
);
2800 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2801 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2804 // Initialize local copy of Value for each Question
2806 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2807 if (EFI_ERROR (Status
)) {
2811 if ((Question
->Operand
== EFI_IFR_STRING_OP
) || (Question
->Operand
== EFI_IFR_PASSWORD_OP
)) {
2812 HiiSetString (FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, (CHAR16
*)Question
->BufferValue
, NULL
);
2816 // According the spec, ref opcode try to get value from call back with "retrieve" type.
2818 if ((Question
->Operand
== EFI_IFR_REF_OP
) && (FormSet
->ConfigAccess
!= NULL
)) {
2819 Status
= ProcessCallBackFunction(Selection
, Question
, EFI_BROWSER_ACTION_RETRIEVE
, TRUE
);
2820 if (EFI_ERROR (Status
)) {
2826 // Check whether EfiVarstore with CallBack can be got.
2828 if ((FormSet
->ConfigAccess
!= NULL
) &&
2829 (Selection
->Action
!= UI_ACTION_REFRESH_FORMSET
) &&
2830 (Question
->QuestionId
!= 0) &&
2831 (Question
->Storage
!= NULL
) &&
2832 (Question
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) &&
2833 ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
2836 // Check QuestionValue does exist.
2838 StorageWidth
= Question
->StorageWidth
;
2839 if (Question
->BufferValue
!= NULL
) {
2840 BufferValue
= Question
->BufferValue
;
2842 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
2844 Status
= gRT
->GetVariable (
2845 Question
->VariableName
,
2846 &Question
->Storage
->Guid
,
2852 if (!EFI_ERROR (Status
)) {
2853 Status
= ProcessCallBackFunction(Selection
, Question
, EFI_BROWSER_ACTION_RETRIEVE
, TRUE
);
2857 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2864 Initialize Question's Edit copy from Storage for the whole Formset.
2866 @param Selection Selection contains the information about
2867 the Selection, form and formset to be displayed.
2868 Selection action may be updated in retrieve callback.
2869 @param FormSet FormSet data structure.
2871 @retval EFI_SUCCESS The function completed successfully.
2876 IN OUT UI_MENU_SELECTION
*Selection
,
2877 IN FORM_BROWSER_FORMSET
*FormSet
2882 FORM_BROWSER_FORM
*Form
;
2884 Link
= GetFirstNode (&FormSet
->FormListHead
);
2885 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2886 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2889 // Initialize local copy of Value for each Form
2891 Status
= LoadFormConfig (Selection
, FormSet
, Form
);
2892 if (EFI_ERROR (Status
)) {
2896 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2903 Fill storage's edit copy with settings requested from Configuration Driver.
2905 @param FormSet FormSet data structure.
2906 @param Storage Buffer Storage.
2908 @retval EFI_SUCCESS The function completed successfully.
2913 IN FORM_BROWSER_FORMSET
*FormSet
,
2914 IN FORMSET_STORAGE
*Storage
2918 EFI_STRING Progress
;
2922 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2926 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
2927 Status
= gRT
->GetVariable (
2931 (UINTN
*)&Storage
->Size
,
2937 if (FormSet
->ConfigAccess
== NULL
) {
2938 return EFI_NOT_FOUND
;
2941 if (Storage
->ElementCount
== 0) {
2943 // Skip if there is no RequestElement
2949 // Request current settings from Configuration Driver
2951 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2952 FormSet
->ConfigAccess
,
2953 Storage
->ConfigRequest
,
2957 if (EFI_ERROR (Status
)) {
2962 // Convert Result from <ConfigAltResp> to <ConfigResp>
2964 StrPtr
= StrStr (Result
, L
"ALTCFG");
2965 if (StrPtr
!= NULL
) {
2969 Status
= ConfigRespToStorage (Storage
, Result
);
2976 Copy uncommitted data from source Storage to destination Storage.
2978 @param Dst Target Storage for uncommitted data.
2979 @param Src Source Storage for uncommitted data.
2981 @retval EFI_SUCCESS The function completed successfully.
2982 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2987 IN OUT FORMSET_STORAGE
*Dst
,
2988 IN FORMSET_STORAGE
*Src
2992 NAME_VALUE_NODE
*Node
;
2994 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2995 return EFI_INVALID_PARAMETER
;
2998 switch (Src
->Type
) {
2999 case EFI_HII_VARSTORE_BUFFER
:
3000 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
3001 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
3002 CopyMem (Dst
->Buffer
, Src
->Buffer
, Src
->Size
);
3005 case EFI_HII_VARSTORE_NAME_VALUE
:
3006 Link
= GetFirstNode (&Src
->NameValueListHead
);
3007 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
3008 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
3010 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
, TRUE
);
3011 SetValueByName (Dst
, Node
->Name
, Node
->Value
, FALSE
);
3013 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
3017 case EFI_HII_VARSTORE_EFI_VARIABLE
:
3027 Get current setting of Questions.
3029 @param FormSet FormSet data structure.
3031 @retval EFI_SUCCESS The function completed successfully.
3035 InitializeCurrentSetting (
3036 IN OUT FORM_BROWSER_FORMSET
*FormSet
3041 FORMSET_STORAGE
*Storage
;
3042 FORMSET_STORAGE
*StorageSrc
;
3043 FORMSET_STORAGE
*OldStorage
;
3044 FORM_BROWSER_FORM
*Form
;
3045 FORM_BROWSER_FORM
*Form2
;
3049 // Extract default from IFR binary
3051 Status
= ExtractFormSetDefault (FormSet
, EFI_HII_DEFAULT_CLASS_STANDARD
);
3052 if (EFI_ERROR (Status
)) {
3057 // Request current settings from Configuration Driver
3059 Link
= GetFirstNode (&FormSet
->StorageListHead
);
3060 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
3061 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
3064 if (gOldFormSet
!= NULL
) {
3066 // Try to find the Storage in backup formset gOldFormSet
3068 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
3069 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
3070 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
3072 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
3073 OldStorage
= StorageSrc
;
3077 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
3081 if (OldStorage
== NULL
) {
3083 // Storage is not found in backup formset, request it from ConfigDriver
3085 Status
= LoadStorage (FormSet
, Storage
);
3087 // Now Edit Buffer is filled with default values(lower priority) and current
3088 // settings(higher priority), sychronize it to shadow Buffer
3090 if (!EFI_ERROR (Status
)) {
3091 SynchronizeStorage (Storage
, TRUE
);
3095 // Storage found in backup formset, use it
3097 Status
= CopyStorage (Storage
, OldStorage
);
3100 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
3104 // If has old formset, get the old nv update status.
3106 if (gOldFormSet
!= NULL
) {
3107 Link
= GetFirstNode (&FormSet
->FormListHead
);
3108 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
3109 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
3111 Link2
= GetFirstNode (&gOldFormSet
->FormListHead
);
3112 while (!IsNull (&gOldFormSet
->FormListHead
, Link2
)) {
3113 Form2
= FORM_BROWSER_FORM_FROM_LINK (Link2
);
3115 if (Form
->FormId
== Form2
->FormId
) {
3116 Form
->NvUpdateRequired
= Form2
->NvUpdateRequired
;
3120 Link2
= GetNextNode (&gOldFormSet
->FormListHead
, Link2
);
3122 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
3131 Fetch the Ifr binary data of a FormSet.
3133 @param Handle PackageList Handle
3134 @param FormSetGuid On input, GUID or class GUID of a formset. If not
3135 specified (NULL or zero GUID), take the first
3136 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
3137 found in package list.
3138 On output, GUID of the formset found(if not NULL).
3139 @param BinaryLength The length of the FormSet IFR binary.
3140 @param BinaryData The buffer designed to receive the FormSet.
3142 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
3143 BufferLength was updated.
3144 @retval EFI_INVALID_PARAMETER The handle is unknown.
3145 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
3146 be found with the requested FormId.
3151 IN EFI_HII_HANDLE Handle
,
3152 IN OUT EFI_GUID
*FormSetGuid
,
3153 OUT UINTN
*BinaryLength
,
3154 OUT UINT8
**BinaryData
3158 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
3164 UINT32 PackageListLength
;
3165 EFI_HII_PACKAGE_HEADER PackageHeader
;
3167 UINT8 NumberOfClassGuid
;
3168 BOOLEAN ClassGuidMatch
;
3169 EFI_GUID
*ClassGuid
;
3170 EFI_GUID
*ComparingGuid
;
3174 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
3177 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
3179 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
3180 ComparingGuid
= &gEfiHiiPlatformSetupFormsetGuid
;
3182 ComparingGuid
= FormSetGuid
;
3186 // Get HII PackageList
3189 HiiPackageList
= NULL
;
3190 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
3191 if (Status
== EFI_BUFFER_TOO_SMALL
) {
3192 HiiPackageList
= AllocatePool (BufferSize
);
3193 ASSERT (HiiPackageList
!= NULL
);
3195 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
3197 if (EFI_ERROR (Status
)) {
3200 ASSERT (HiiPackageList
!= NULL
);
3203 // Get Form package from this HII package List
3205 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
3207 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
3209 ClassGuidMatch
= FALSE
;
3210 while (Offset
< PackageListLength
) {
3211 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
3212 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
3214 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
3216 // Search FormSet in this Form Package
3218 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
3219 while (Offset2
< PackageHeader
.Length
) {
3220 OpCodeData
= Package
+ Offset2
;
3222 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
3224 // Try to compare against formset GUID
3226 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
3230 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
3232 // Try to compare against formset class GUID
3234 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
3235 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
3236 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
3237 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
3238 ClassGuidMatch
= TRUE
;
3242 if (ClassGuidMatch
) {
3245 } else if (ComparingGuid
== &gEfiHiiPlatformSetupFormsetGuid
) {
3246 ClassGuidMatch
= TRUE
;
3251 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
3254 if (Offset2
< PackageHeader
.Length
) {
3256 // Target formset found
3262 Offset
+= PackageHeader
.Length
;
3265 if (Offset
>= PackageListLength
) {
3267 // Form package not found in this Package List
3269 FreePool (HiiPackageList
);
3270 return EFI_NOT_FOUND
;
3273 if (ClassGuidMatch
&& (FormSetGuid
!= NULL
)) {
3275 // Return the FormSet GUID
3277 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
3281 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
3282 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
3283 // of the Form Package.
3285 *BinaryLength
= PackageHeader
.Length
- Offset2
;
3286 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
3288 FreePool (HiiPackageList
);
3290 if (*BinaryData
== NULL
) {
3291 return EFI_OUT_OF_RESOURCES
;
3299 Initialize the internal data structure of a FormSet.
3301 @param Handle PackageList Handle
3302 @param FormSetGuid On input, GUID or class GUID of a formset. If not
3303 specified (NULL or zero GUID), take the first
3304 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
3305 found in package list.
3306 On output, GUID of the formset found(if not NULL).
3307 @param FormSet FormSet data structure.
3309 @retval EFI_SUCCESS The function completed successfully.
3310 @retval EFI_NOT_FOUND The specified FormSet could not be found.
3315 IN EFI_HII_HANDLE Handle
,
3316 IN OUT EFI_GUID
*FormSetGuid
,
3317 OUT FORM_BROWSER_FORMSET
*FormSet
3321 EFI_HANDLE DriverHandle
;
3324 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
3325 if (EFI_ERROR (Status
)) {
3329 FormSet
->HiiHandle
= Handle
;
3330 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
3333 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
3335 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
3336 if (EFI_ERROR (Status
)) {
3339 FormSet
->DriverHandle
= DriverHandle
;
3340 Status
= gBS
->HandleProtocol (
3342 &gEfiHiiConfigAccessProtocolGuid
,
3343 (VOID
**) &FormSet
->ConfigAccess
3345 if (EFI_ERROR (Status
)) {
3347 // Configuration Driver don't attach ConfigAccess protocol to its HII package
3348 // list, then there will be no configuration action required
3350 FormSet
->ConfigAccess
= NULL
;
3354 // Parse the IFR binary OpCodes
3356 Status
= ParseOpCodes (FormSet
);
3357 if (EFI_ERROR (Status
)) {
3362 // Set VFR type by FormSet SubClass field
3364 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
3365 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
3366 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
3370 // Set VFR type by FormSet class guid
3372 for (Index
= 0; Index
< 3; Index
++) {
3373 if (CompareGuid (&FormSet
->ClassGuid
[Index
], &gEfiHiiPlatformSetupFormsetGuid
)) {
3374 gClassOfVfr
|= FORMSET_CLASS_PLATFORM_SETUP
;
3379 if ((gClassOfVfr
& FORMSET_CLASS_FRONT_PAGE
) == FORMSET_CLASS_FRONT_PAGE
) {
3380 gFrontPageHandle
= FormSet
->HiiHandle
;
3384 // Match GUID to find out the function key setting. If match fail, use the default setting.
3386 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
3387 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
3389 // Update the function key setting.
3391 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
3393 // Function key prompt can not be displayed if the function key has been disabled.
3395 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
3396 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
3399 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
3400 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
3410 Save globals used by previous call to SendForm(). SendForm() may be called from
3411 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
3412 So, save globals of previous call to SendForm() and restore them upon exit.
3416 SaveBrowserContext (
3420 BROWSER_CONTEXT
*Context
;
3422 gBrowserContextCount
++;
3423 if (gBrowserContextCount
== 1) {
3425 // This is not reentry of SendForm(), no context to save
3430 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
3431 ASSERT (Context
!= NULL
);
3433 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
3436 // Save FormBrowser context
3438 Context
->BannerData
= gBannerData
;
3439 Context
->ClassOfVfr
= gClassOfVfr
;
3440 Context
->FunctionKeySetting
= gFunctionKeySetting
;
3441 Context
->ResetRequired
= gResetRequired
;
3442 Context
->Direction
= gDirection
;
3443 Context
->FunctionNineString
= gFunctionNineString
;
3444 Context
->FunctionTenString
= gFunctionTenString
;
3445 Context
->EnterString
= gEnterString
;
3446 Context
->EnterCommitString
= gEnterCommitString
;
3447 Context
->EnterEscapeString
= gEnterEscapeString
;
3448 Context
->EscapeString
= gEscapeString
;
3449 Context
->SaveFailed
= gSaveFailed
;
3450 Context
->MoveHighlight
= gMoveHighlight
;
3451 Context
->MakeSelection
= gMakeSelection
;
3452 Context
->DecNumericInput
= gDecNumericInput
;
3453 Context
->HexNumericInput
= gHexNumericInput
;
3454 Context
->ToggleCheckBox
= gToggleCheckBox
;
3455 Context
->PromptForData
= gPromptForData
;
3456 Context
->PromptForPassword
= gPromptForPassword
;
3457 Context
->PromptForNewPassword
= gPromptForNewPassword
;
3458 Context
->ConfirmPassword
= gConfirmPassword
;
3459 Context
->ConfirmError
= gConfirmError
;
3460 Context
->PassowordInvalid
= gPassowordInvalid
;
3461 Context
->PressEnter
= gPressEnter
;
3462 Context
->EmptyString
= gEmptyString
;
3463 Context
->AreYouSure
= gAreYouSure
;
3464 Context
->YesResponse
= gYesResponse
;
3465 Context
->NoResponse
= gNoResponse
;
3466 Context
->MiniString
= gMiniString
;
3467 Context
->PlusString
= gPlusString
;
3468 Context
->MinusString
= gMinusString
;
3469 Context
->AdjustNumber
= gAdjustNumber
;
3470 Context
->SaveChanges
= gSaveChanges
;
3471 Context
->OptionMismatch
= gOptionMismatch
;
3472 Context
->FormSuppress
= gFormSuppress
;
3473 Context
->PromptBlockWidth
= gPromptBlockWidth
;
3474 Context
->OptionBlockWidth
= gOptionBlockWidth
;
3475 Context
->HelpBlockWidth
= gHelpBlockWidth
;
3476 Context
->OldFormSet
= gOldFormSet
;
3477 Context
->MenuRefreshHead
= gMenuRefreshHead
;
3479 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
3480 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
3483 // Insert to FormBrowser context list
3485 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
3490 Restore globals used by previous call to SendForm().
3494 RestoreBrowserContext (
3499 BROWSER_CONTEXT
*Context
;
3501 ASSERT (gBrowserContextCount
!= 0);
3502 gBrowserContextCount
--;
3503 if (gBrowserContextCount
== 0) {
3505 // This is not reentry of SendForm(), no context to restore
3510 ASSERT (!IsListEmpty (&gBrowserContextList
));
3512 Link
= GetFirstNode (&gBrowserContextList
);
3513 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
3516 // Restore FormBrowser context
3518 gBannerData
= Context
->BannerData
;
3519 gClassOfVfr
= Context
->ClassOfVfr
;
3520 gFunctionKeySetting
= Context
->FunctionKeySetting
;
3521 gResetRequired
= Context
->ResetRequired
;
3522 gDirection
= Context
->Direction
;
3523 gFunctionNineString
= Context
->FunctionNineString
;
3524 gFunctionTenString
= Context
->FunctionTenString
;
3525 gEnterString
= Context
->EnterString
;
3526 gEnterCommitString
= Context
->EnterCommitString
;
3527 gEnterEscapeString
= Context
->EnterEscapeString
;
3528 gEscapeString
= Context
->EscapeString
;
3529 gSaveFailed
= Context
->SaveFailed
;
3530 gMoveHighlight
= Context
->MoveHighlight
;
3531 gMakeSelection
= Context
->MakeSelection
;
3532 gDecNumericInput
= Context
->DecNumericInput
;
3533 gHexNumericInput
= Context
->HexNumericInput
;
3534 gToggleCheckBox
= Context
->ToggleCheckBox
;
3535 gPromptForData
= Context
->PromptForData
;
3536 gPromptForPassword
= Context
->PromptForPassword
;
3537 gPromptForNewPassword
= Context
->PromptForNewPassword
;
3538 gConfirmPassword
= Context
->ConfirmPassword
;
3539 gConfirmError
= Context
->ConfirmError
;
3540 gPassowordInvalid
= Context
->PassowordInvalid
;
3541 gPressEnter
= Context
->PressEnter
;
3542 gEmptyString
= Context
->EmptyString
;
3543 gAreYouSure
= Context
->AreYouSure
;
3544 gYesResponse
= Context
->YesResponse
;
3545 gNoResponse
= Context
->NoResponse
;
3546 gMiniString
= Context
->MiniString
;
3547 gPlusString
= Context
->PlusString
;
3548 gMinusString
= Context
->MinusString
;
3549 gAdjustNumber
= Context
->AdjustNumber
;
3550 gSaveChanges
= Context
->SaveChanges
;
3551 gOptionMismatch
= Context
->OptionMismatch
;
3552 gFormSuppress
= Context
->FormSuppress
;
3553 gPromptBlockWidth
= Context
->PromptBlockWidth
;
3554 gOptionBlockWidth
= Context
->OptionBlockWidth
;
3555 gHelpBlockWidth
= Context
->HelpBlockWidth
;
3556 gOldFormSet
= Context
->OldFormSet
;
3557 gMenuRefreshHead
= Context
->MenuRefreshHead
;
3559 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
3560 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
3563 // Remove from FormBrowser context list
3565 RemoveEntryList (&Context
->Link
);
3566 gBS
->FreePool (Context
);