2 Entry and initialization module for the browser.
4 Copyright (c) 2007 - 2009, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 SETUP_DRIVER_PRIVATE_DATA mPrivateData
= {
20 SETUP_DRIVER_SIGNATURE
,
28 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
29 EFI_HII_STRING_PROTOCOL
*mHiiString
;
30 EFI_HII_CONFIG_ROUTING_PROTOCOL
*mHiiConfigRouting
;
32 UINTN gBrowserContextCount
= 0;
33 LIST_ENTRY gBrowserContextList
= INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList
);
35 BANNER_DATA
*gBannerData
;
36 EFI_HII_HANDLE gFrontPageHandle
;
38 UINTN gFunctionKeySetting
;
39 BOOLEAN gResetRequired
;
40 BOOLEAN gNvUpdateRequired
;
41 EFI_HII_HANDLE gHiiHandle
;
43 EFI_SCREEN_DESCRIPTOR gScreenDimensions
;
46 // Browser Global Strings
48 CHAR16
*gFunctionNineString
;
49 CHAR16
*gFunctionTenString
;
51 CHAR16
*gEnterCommitString
;
52 CHAR16
*gEnterEscapeString
;
53 CHAR16
*gEscapeString
;
55 CHAR16
*gMoveHighlight
;
56 CHAR16
*gMakeSelection
;
57 CHAR16
*gDecNumericInput
;
58 CHAR16
*gHexNumericInput
;
59 CHAR16
*gToggleCheckBox
;
60 CHAR16
*gPromptForData
;
61 CHAR16
*gPromptForPassword
;
62 CHAR16
*gPromptForNewPassword
;
63 CHAR16
*gConfirmPassword
;
64 CHAR16
*gConfirmError
;
65 CHAR16
*gPassowordInvalid
;
74 CHAR16
*gAdjustNumber
;
76 CHAR16
*gOptionMismatch
;
77 CHAR16
*gFormSuppress
;
79 CHAR16
*mUnknownString
= L
"!";
81 CHAR16 gPromptBlockWidth
;
82 CHAR16 gOptionBlockWidth
;
83 CHAR16 gHelpBlockWidth
;
85 EFI_GUID gZeroGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
86 EFI_GUID gSetupBrowserGuid
= {
87 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
90 FORM_BROWSER_FORMSET
*gOldFormSet
;
92 FUNCTIION_KEY_SETTING gFunctionKeySettingTable
[] = {
112 NONE_FUNCTION_KEY_SETTING
133 NONE_FUNCTION_KEY_SETTING
154 NONE_FUNCTION_KEY_SETTING
157 // BMM File Explorer FormSet.
175 NONE_FUNCTION_KEY_SETTING
180 This is the routine which an external caller uses to direct the browser
181 where to obtain it's information.
184 @param This The Form Browser protocol instanse.
185 @param Handles A pointer to an array of Handles. If HandleCount > 1 we
186 display a list of the formsets for the handles specified.
187 @param HandleCount The number of Handles specified in Handle.
188 @param FormSetGuid This field points to the EFI_GUID which must match the Guid
189 field in the EFI_IFR_FORM_SET op-code for the specified
190 forms-based package. If FormSetGuid is NULL, then this
191 function will display the first found forms package.
192 @param FormId This field specifies which EFI_IFR_FORM to render as the first
193 displayable page. If this field has a value of 0x0000, then
194 the forms browser will render the specified forms in their encoded order.
195 @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in
197 @param ActionRequest Points to the action recommended by the form.
199 @retval EFI_SUCCESS The function completed successfully.
200 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
201 @retval EFI_NOT_FOUND No valid forms could be found to display.
207 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
208 IN EFI_HII_HANDLE
*Handles
,
209 IN UINTN HandleCount
,
210 IN EFI_GUID
*FormSetGuid
, OPTIONAL
211 IN UINT16 FormId
, OPTIONAL
212 IN CONST EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
213 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest OPTIONAL
217 UI_MENU_SELECTION
*Selection
;
219 FORM_BROWSER_FORMSET
*FormSet
;
222 // Save globals used by SendForm()
224 SaveBrowserContext ();
226 Status
= EFI_SUCCESS
;
227 ZeroMem (&gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
230 // Seed the dimensions in the global
232 gST
->ConOut
->QueryMode (
234 gST
->ConOut
->Mode
->Mode
,
235 &gScreenDimensions
.RightColumn
,
236 &gScreenDimensions
.BottomRow
239 if (ScreenDimensions
!= NULL
) {
241 // Check local dimension vs. global dimension.
243 if ((gScreenDimensions
.RightColumn
< ScreenDimensions
->RightColumn
) ||
244 (gScreenDimensions
.BottomRow
< ScreenDimensions
->BottomRow
)
246 Status
= EFI_INVALID_PARAMETER
;
250 // Local dimension validation.
252 if ((ScreenDimensions
->RightColumn
> ScreenDimensions
->LeftColumn
) &&
253 (ScreenDimensions
->BottomRow
> ScreenDimensions
->TopRow
) &&
254 ((ScreenDimensions
->RightColumn
- ScreenDimensions
->LeftColumn
) > 2) &&
256 (ScreenDimensions
->BottomRow
- ScreenDimensions
->TopRow
) > STATUS_BAR_HEIGHT
+
257 SCROLL_ARROW_HEIGHT
*
259 FRONT_PAGE_HEADER_HEIGHT
+
264 CopyMem (&gScreenDimensions
, (VOID
*) ScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
266 Status
= EFI_INVALID_PARAMETER
;
272 gOptionBlockWidth
= (CHAR16
) ((gScreenDimensions
.RightColumn
- gScreenDimensions
.LeftColumn
) / 3);
273 gHelpBlockWidth
= gOptionBlockWidth
;
274 gPromptBlockWidth
= gOptionBlockWidth
;
277 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
279 InitializeBrowserStrings ();
281 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
282 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
285 // Ensure we are in Text mode
287 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
289 for (Index
= 0; Index
< HandleCount
; Index
++) {
290 Selection
= AllocateZeroPool (sizeof (UI_MENU_SELECTION
));
291 ASSERT (Selection
!= NULL
);
293 Selection
->Handle
= Handles
[Index
];
294 if (FormSetGuid
!= NULL
) {
295 CopyMem (&Selection
->FormSetGuid
, FormSetGuid
, sizeof (EFI_GUID
));
296 Selection
->FormId
= FormId
;
300 gNvUpdateRequired
= FALSE
;
303 FormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
304 ASSERT (FormSet
!= NULL
);
307 // Initialize internal data structures of FormSet
309 Status
= InitializeFormSet (Selection
->Handle
, &Selection
->FormSetGuid
, FormSet
);
310 if (EFI_ERROR (Status
) || IsListEmpty (&FormSet
->FormListHead
)) {
311 DestroyFormSet (FormSet
);
314 Selection
->FormSet
= FormSet
;
317 // Display this formset
319 gCurrentSelection
= Selection
;
321 Status
= SetupBrowser (Selection
);
323 gCurrentSelection
= NULL
;
325 if (EFI_ERROR (Status
)) {
329 } while (Selection
->Action
== UI_ACTION_REFRESH_FORMSET
);
331 if (gOldFormSet
!= NULL
) {
332 DestroyFormSet (gOldFormSet
);
336 FreePool (Selection
);
339 if (ActionRequest
!= NULL
) {
340 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
341 if (gResetRequired
) {
342 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
346 FreeBrowserStrings ();
348 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
349 gST
->ConOut
->ClearScreen (gST
->ConOut
);
353 // Restore globals used by SendForm()
355 RestoreBrowserContext ();
362 This function is called by a callback handler to retrieve uncommitted state
363 data from the browser.
365 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
367 @param ResultsDataSize A pointer to the size of the buffer associated
369 @param ResultsData A string returned from an IFR browser or
370 equivalent. The results string will have no
371 routing information in them.
372 @param RetrieveData A BOOLEAN field which allows an agent to retrieve
373 (if RetrieveData = TRUE) data from the uncommitted
374 browser state information or set (if RetrieveData
375 = FALSE) data in the uncommitted browser state
377 @param VariableGuid An optional field to indicate the target variable
379 @param VariableName An optional field to indicate the target
380 human-readable variable name.
382 @retval EFI_SUCCESS The results have been distributed or are awaiting
384 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to
385 contain the results data.
391 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
392 IN OUT UINTN
*ResultsDataSize
,
393 IN OUT EFI_STRING ResultsData
,
394 IN BOOLEAN RetrieveData
,
395 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
396 IN CONST CHAR16
*VariableName OPTIONAL
401 FORMSET_STORAGE
*Storage
;
402 FORM_BROWSER_FORMSET
*FormSet
;
409 if (ResultsDataSize
== NULL
|| ResultsData
== NULL
) {
410 return EFI_INVALID_PARAMETER
;
413 if (gCurrentSelection
== NULL
) {
414 return EFI_NOT_READY
;
419 FormSet
= gCurrentSelection
->FormSet
;
422 // Find target storage
424 Link
= GetFirstNode (&FormSet
->StorageListHead
);
425 if (IsNull (&FormSet
->StorageListHead
, Link
)) {
426 return EFI_UNSUPPORTED
;
429 if (VariableGuid
!= NULL
) {
431 // Try to find target storage
434 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
435 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
436 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
438 if (CompareGuid (&Storage
->Guid
, (EFI_GUID
*) VariableGuid
)) {
439 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
441 // Buffer storage require both GUID and Name
443 if (VariableName
== NULL
) {
444 return EFI_NOT_FOUND
;
447 if (StrCmp (Storage
->Name
, (CHAR16
*) VariableName
) != 0) {
457 return EFI_NOT_FOUND
;
461 // GUID/Name is not specified, take the first storage in FormSet
463 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
468 // Skip if there is no RequestElement
470 if (Storage
->ElementCount
== 0) {
475 // Generate <ConfigResp>
477 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
478 if (EFI_ERROR (Status
)) {
483 // Skip <ConfigHdr> and '&' to point to <ConfigBody>
485 StrPtr
= ConfigResp
+ StrLen (Storage
->ConfigHdr
) + 1;
487 BufferSize
= StrSize (StrPtr
);
488 if (*ResultsDataSize
< BufferSize
) {
489 *ResultsDataSize
= BufferSize
;
491 FreePool (ConfigResp
);
492 return EFI_BUFFER_TOO_SMALL
;
495 *ResultsDataSize
= BufferSize
;
496 CopyMem (ResultsData
, StrPtr
, BufferSize
);
498 FreePool (ConfigResp
);
501 // Prepare <ConfigResp>
503 TmpSize
= StrLen (ResultsData
);
504 BufferSize
= (TmpSize
+ StrLen (Storage
->ConfigHdr
) + 2) * sizeof (CHAR16
);
505 ConfigResp
= AllocateZeroPool (BufferSize
);
506 ASSERT (ConfigResp
!= NULL
);
508 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
509 StrCat (ConfigResp
, L
"&");
510 StrCat (ConfigResp
, ResultsData
);
513 // Update Browser uncommited data
515 Status
= ConfigRespToStorage (Storage
, ConfigResp
);
516 if (EFI_ERROR (Status
)) {
526 Initialize Setup Browser driver.
528 @param ImageHandle The image handle.
529 @param SystemTable The system table.
531 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
532 @return Other value if failed to initialize the Setup Browser module.
538 IN EFI_HANDLE ImageHandle
,
539 IN EFI_SYSTEM_TABLE
*SystemTable
545 // Locate required Hii relative protocols
547 Status
= gBS
->LocateProtocol (
548 &gEfiHiiDatabaseProtocolGuid
,
550 (VOID
**) &mHiiDatabase
552 ASSERT_EFI_ERROR (Status
);
554 Status
= gBS
->LocateProtocol (
555 &gEfiHiiStringProtocolGuid
,
557 (VOID
**) &mHiiString
559 ASSERT_EFI_ERROR (Status
);
561 Status
= gBS
->LocateProtocol (
562 &gEfiHiiConfigRoutingProtocolGuid
,
564 (VOID
**) &mHiiConfigRouting
566 ASSERT_EFI_ERROR (Status
);
569 // Publish our HII data
571 gHiiHandle
= HiiAddPackages (
577 ASSERT (gHiiHandle
!= NULL
);
580 // Initialize Driver private data
582 gBannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
583 ASSERT (gBannerData
!= NULL
);
586 // Install FormBrowser2 protocol
588 mPrivateData
.Handle
= NULL
;
589 Status
= gBS
->InstallProtocolInterface (
590 &mPrivateData
.Handle
,
591 &gEfiFormBrowser2ProtocolGuid
,
592 EFI_NATIVE_INTERFACE
,
593 &mPrivateData
.FormBrowser2
595 ASSERT_EFI_ERROR (Status
);
602 Create a new string in HII Package List.
604 @param String The String to be added
605 @param HiiHandle The package list in the HII database to insert the
608 @return The output string.
614 IN EFI_HII_HANDLE HiiHandle
617 EFI_STRING_ID StringId
;
619 StringId
= HiiSetString (HiiHandle
, 0, String
, NULL
);
620 ASSERT (StringId
!= 0);
627 Delete a string from HII Package List.
629 @param StringId Id of the string in HII database.
630 @param HiiHandle The HII package list handle.
632 @retval EFI_SUCCESS The string was deleted successfully.
637 IN EFI_STRING_ID StringId
,
638 IN EFI_HII_HANDLE HiiHandle
643 NullChar
= CHAR_NULL
;
644 HiiSetString (HiiHandle
, StringId
, &NullChar
, NULL
);
650 Get the string based on the StringId and HII Package List Handle.
652 @param Token The String's ID.
653 @param HiiHandle The package list in the HII database to search for
654 the specified string.
656 @return The output string.
661 IN EFI_STRING_ID Token
,
662 IN EFI_HII_HANDLE HiiHandle
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 Storage's Edit copy to Shadow copy.
733 @param Storage The Storage to be synchronized.
738 IN FORMSET_STORAGE
*Storage
742 NAME_VALUE_NODE
*Node
;
744 switch (Storage
->Type
) {
745 case EFI_HII_VARSTORE_BUFFER
:
746 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
749 case EFI_HII_VARSTORE_NAME_VALUE
:
750 Link
= GetFirstNode (&Storage
->NameValueListHead
);
751 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
752 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
754 NewStringCpy (&Node
->Value
, Node
->EditValue
);
756 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
760 case EFI_HII_VARSTORE_EFI_VARIABLE
:
768 Get Value for given Name from a NameValue Storage.
770 @param Storage The NameValue Storage.
771 @param Name The Name.
772 @param Value The retured Value.
774 @retval EFI_SUCCESS Value found for given Name.
775 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
780 IN FORMSET_STORAGE
*Storage
,
782 IN OUT CHAR16
**Value
786 NAME_VALUE_NODE
*Node
;
790 Link
= GetFirstNode (&Storage
->NameValueListHead
);
791 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
792 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
794 if (StrCmp (Name
, Node
->Name
) == 0) {
795 NewStringCpy (Value
, Node
->EditValue
);
799 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
802 return EFI_NOT_FOUND
;
807 Set Value of given Name in a NameValue Storage.
809 @param Storage The NameValue Storage.
810 @param Name The Name.
811 @param Value The Value to set.
813 @retval EFI_SUCCESS Value found for given Name.
814 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
819 IN FORMSET_STORAGE
*Storage
,
825 NAME_VALUE_NODE
*Node
;
827 Link
= GetFirstNode (&Storage
->NameValueListHead
);
828 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
829 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
831 if (StrCmp (Name
, Node
->Name
) == 0) {
832 if (Node
->EditValue
!= NULL
) {
833 FreePool (Node
->EditValue
);
835 Node
->EditValue
= AllocateCopyPool (StrSize (Value
), Value
);
836 ASSERT (Node
->EditValue
!= NULL
);
840 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
843 return EFI_NOT_FOUND
;
848 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
850 @param Storage The Storage to be conveted.
851 @param ConfigResp The returned <ConfigResp>.
853 @retval EFI_SUCCESS Convert success.
854 @retval EFI_INVALID_PARAMETER Incorrect storage type.
858 StorageToConfigResp (
859 IN FORMSET_STORAGE
*Storage
,
860 IN CHAR16
**ConfigResp
866 NAME_VALUE_NODE
*Node
;
868 Status
= EFI_SUCCESS
;
870 switch (Storage
->Type
) {
871 case EFI_HII_VARSTORE_BUFFER
:
872 Status
= mHiiConfigRouting
->BlockToConfig (
874 Storage
->ConfigRequest
,
882 case EFI_HII_VARSTORE_NAME_VALUE
:
884 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
886 Link
= GetFirstNode (&Storage
->NameValueListHead
);
887 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
888 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
890 NewStringCat (ConfigResp
, L
"&");
891 NewStringCat (ConfigResp
, Node
->Name
);
892 NewStringCat (ConfigResp
, L
"=");
893 NewStringCat (ConfigResp
, Node
->EditValue
);
895 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
899 case EFI_HII_VARSTORE_EFI_VARIABLE
:
901 Status
= EFI_INVALID_PARAMETER
;
910 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
912 @param Storage The Storage to receive the settings.
913 @param ConfigResp The <ConfigResp> to be converted.
915 @retval EFI_SUCCESS Convert success.
916 @retval EFI_INVALID_PARAMETER Incorrect storage type.
920 ConfigRespToStorage (
921 IN FORMSET_STORAGE
*Storage
,
922 IN CHAR16
*ConfigResp
932 Status
= EFI_SUCCESS
;
934 switch (Storage
->Type
) {
935 case EFI_HII_VARSTORE_BUFFER
:
936 BufferSize
= Storage
->Size
;
937 Status
= mHiiConfigRouting
->ConfigToBlock (
946 case EFI_HII_VARSTORE_NAME_VALUE
:
947 StrPtr
= StrStr (ConfigResp
, L
"&");
948 while (StrPtr
!= NULL
) {
954 StrPtr
= StrStr (StrPtr
, L
"=");
955 if (StrPtr
== NULL
) {
965 StrPtr
= StrStr (StrPtr
, L
"&");
966 if (StrPtr
!= NULL
) {
969 SetValueByName (Storage
, Name
, Value
);
973 case EFI_HII_VARSTORE_EFI_VARIABLE
:
975 Status
= EFI_INVALID_PARAMETER
;
984 Get Question's current Value.
986 @param FormSet FormSet data structure.
987 @param Form Form data structure.
988 @param Question Question to be initialized.
989 @param Cached TRUE: get from Edit copy FALSE: get from original
992 @retval EFI_SUCCESS The function completed successfully.
997 IN FORM_BROWSER_FORMSET
*FormSet
,
998 IN FORM_BROWSER_FORM
*Form
,
999 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1009 FORMSET_STORAGE
*Storage
;
1010 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1011 CHAR16
*ConfigRequest
;
1019 BOOLEAN IsBufferStorage
;
1024 Status
= EFI_SUCCESS
;
1027 // Statement don't have storage, skip them
1029 if (Question
->QuestionId
== 0) {
1034 // Question value is provided by an Expression, evaluate it
1036 if (Question
->ValueExpression
!= NULL
) {
1037 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1038 if (!EFI_ERROR (Status
)) {
1039 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1045 // Question value is provided by RTC
1047 Storage
= Question
->Storage
;
1048 QuestionValue
= &Question
->HiiValue
.Value
;
1049 if (Storage
== NULL
) {
1051 // It's a Question without storage, or RTC date/time
1053 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1055 // Date and time define the same Flags bit
1057 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1058 case QF_DATE_STORAGE_TIME
:
1059 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1062 case QF_DATE_STORAGE_WAKEUP
:
1063 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1066 case QF_DATE_STORAGE_NORMAL
:
1069 // For date/time without storage
1074 if (EFI_ERROR (Status
)) {
1078 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1079 QuestionValue
->date
.Year
= EfiTime
.Year
;
1080 QuestionValue
->date
.Month
= EfiTime
.Month
;
1081 QuestionValue
->date
.Day
= EfiTime
.Day
;
1083 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1084 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1085 QuestionValue
->time
.Second
= EfiTime
.Second
;
1093 // Question value is provided by EFI variable
1095 StorageWidth
= Question
->StorageWidth
;
1096 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1097 if (Question
->BufferValue
!= NULL
) {
1098 Dst
= Question
->BufferValue
;
1100 Dst
= (UINT8
*) QuestionValue
;
1103 Status
= gRT
->GetVariable (
1104 Question
->VariableName
,
1111 // Always return success, even this EFI variable doesn't exist
1117 // Question Value is provided by Buffer Storage or NameValue Storage
1119 if (Question
->BufferValue
!= NULL
) {
1121 // This Question is password or orderedlist
1123 Dst
= Question
->BufferValue
;
1126 // Other type of Questions
1128 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1131 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1132 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1134 if (IsBufferStorage
) {
1136 // Copy from storage Edit buffer
1138 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1140 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1141 if (EFI_ERROR (Status
)) {
1145 LengthStr
= StrLen (Value
);
1146 Status
= EFI_SUCCESS
;
1149 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1150 // Add string tail char L'\0' into Length
1152 Length
= StorageWidth
+ sizeof (CHAR16
);
1153 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1154 Status
= EFI_BUFFER_TOO_SMALL
;
1156 StringPtr
= (CHAR16
*) Dst
;
1157 ZeroMem (TemStr
, sizeof (TemStr
));
1158 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1159 StrnCpy (TemStr
, Value
+ Index
, 4);
1160 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1163 // Add tailing L'\0' character
1165 StringPtr
[Index
/4] = L
'\0';
1168 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1169 Status
= EFI_BUFFER_TOO_SMALL
;
1171 ZeroMem (TemStr
, sizeof (TemStr
));
1172 for (Index
= 0; Index
< LengthStr
; Index
++) {
1173 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1174 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1175 if ((Index
& 1) == 0) {
1176 Dst
[Index
/2] = DigitUint8
;
1178 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1188 // Request current settings from Configuration Driver
1190 if (FormSet
->ConfigAccess
== NULL
) {
1191 return EFI_NOT_FOUND
;
1195 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1196 // <ConfigHdr> + "&" + <VariableName>
1198 if (IsBufferStorage
) {
1199 Length
= StrLen (Storage
->ConfigHdr
);
1200 Length
+= StrLen (Question
->BlockName
);
1202 Length
= StrLen (Storage
->ConfigHdr
);
1203 Length
+= StrLen (Question
->VariableName
) + 1;
1205 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1206 ASSERT (ConfigRequest
!= NULL
);
1208 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1209 if (IsBufferStorage
) {
1210 StrCat (ConfigRequest
, Question
->BlockName
);
1212 StrCat (ConfigRequest
, L
"&");
1213 StrCat (ConfigRequest
, Question
->VariableName
);
1216 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1217 FormSet
->ConfigAccess
,
1222 if (EFI_ERROR (Status
)) {
1227 // Skip <ConfigRequest>
1229 Value
= Result
+ Length
;
1230 if (IsBufferStorage
) {
1236 if (*Value
!= '=') {
1238 return EFI_NOT_FOUND
;
1241 // Skip '=', point to value
1246 // Suppress <AltResp> if any
1249 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1254 LengthStr
= StrLen (Value
);
1255 Status
= EFI_SUCCESS
;
1256 if (!IsBufferStorage
&& IsString
) {
1258 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1259 // Add string tail char L'\0' into Length
1261 Length
= StorageWidth
+ sizeof (CHAR16
);
1262 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1263 Status
= EFI_BUFFER_TOO_SMALL
;
1265 StringPtr
= (CHAR16
*) Dst
;
1266 ZeroMem (TemStr
, sizeof (TemStr
));
1267 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1268 StrnCpy (TemStr
, Value
+ Index
, 4);
1269 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1272 // Add tailing L'\0' character
1274 StringPtr
[Index
/4] = L
'\0';
1277 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1278 Status
= EFI_BUFFER_TOO_SMALL
;
1280 ZeroMem (TemStr
, sizeof (TemStr
));
1281 for (Index
= 0; Index
< LengthStr
; Index
++) {
1282 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1283 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1284 if ((Index
& 1) == 0) {
1285 Dst
[Index
/2] = DigitUint8
;
1287 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1293 if (EFI_ERROR (Status
)) {
1299 // Synchronize Edit Buffer
1301 if (IsBufferStorage
) {
1302 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1304 SetValueByName (Storage
, Question
->VariableName
, Value
);
1315 Save Question Value to edit copy(cached) or Storage(uncached).
1317 @param FormSet FormSet data structure.
1318 @param Form Form data structure.
1319 @param Question Pointer to the Question.
1320 @param Cached TRUE: set to Edit copy FALSE: set to original
1323 @retval EFI_SUCCESS The function completed successfully.
1328 IN FORM_BROWSER_FORMSET
*FormSet
,
1329 IN FORM_BROWSER_FORM
*Form
,
1330 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1341 FORMSET_STORAGE
*Storage
;
1342 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1347 BOOLEAN IsBufferStorage
;
1354 Status
= EFI_SUCCESS
;
1357 // Statement don't have storage, skip them
1359 if (Question
->QuestionId
== 0) {
1364 // If Question value is provided by an Expression, then it is read only
1366 if (Question
->ValueExpression
!= NULL
) {
1371 // Question value is provided by RTC
1373 Storage
= Question
->Storage
;
1374 QuestionValue
= &Question
->HiiValue
.Value
;
1375 if (Storage
== NULL
) {
1377 // It's a Question without storage, or RTC date/time
1379 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1381 // Date and time define the same Flags bit
1383 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1384 case QF_DATE_STORAGE_TIME
:
1385 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1388 case QF_DATE_STORAGE_WAKEUP
:
1389 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1392 case QF_DATE_STORAGE_NORMAL
:
1395 // For date/time without storage
1400 if (EFI_ERROR (Status
)) {
1404 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1405 EfiTime
.Year
= QuestionValue
->date
.Year
;
1406 EfiTime
.Month
= QuestionValue
->date
.Month
;
1407 EfiTime
.Day
= QuestionValue
->date
.Day
;
1409 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1410 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1411 EfiTime
.Second
= QuestionValue
->time
.Second
;
1414 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1415 Status
= gRT
->SetTime (&EfiTime
);
1417 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1425 // Question value is provided by EFI variable
1427 StorageWidth
= Question
->StorageWidth
;
1428 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1429 if (Question
->BufferValue
!= NULL
) {
1430 Src
= Question
->BufferValue
;
1432 Src
= (UINT8
*) QuestionValue
;
1435 Status
= gRT
->SetVariable (
1436 Question
->VariableName
,
1438 Storage
->Attributes
,
1446 // Question Value is provided by Buffer Storage or NameValue Storage
1448 if (Question
->BufferValue
!= NULL
) {
1449 Src
= Question
->BufferValue
;
1451 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1454 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1455 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1456 if (IsBufferStorage
) {
1458 // Copy to storage edit buffer
1460 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1464 // Allocate enough string buffer.
1467 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1468 Value
= AllocateZeroPool (BufferLen
);
1469 ASSERT (Value
!= NULL
);
1471 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1473 TemName
= (CHAR16
*) Src
;
1475 for (; *TemName
!= L
'\0'; TemName
++) {
1476 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1479 BufferLen
= StorageWidth
* 2 + 1;
1480 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1481 ASSERT (Value
!= NULL
);
1483 // Convert Buffer to Hex String
1485 TemBuffer
= Src
+ StorageWidth
- 1;
1487 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1488 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1492 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
);
1498 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1499 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1501 if (IsBufferStorage
) {
1502 Length
= StrLen (Question
->BlockName
) + 7;
1504 Length
= StrLen (Question
->VariableName
) + 2;
1506 if (!IsBufferStorage
&& IsString
) {
1507 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1509 Length
+= (StorageWidth
* 2);
1511 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1512 ASSERT (ConfigResp
!= NULL
);
1514 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1515 if (IsBufferStorage
) {
1516 StrCat (ConfigResp
, Question
->BlockName
);
1517 StrCat (ConfigResp
, L
"&VALUE=");
1519 StrCat (ConfigResp
, L
"&");
1520 StrCat (ConfigResp
, Question
->VariableName
);
1521 StrCat (ConfigResp
, L
"=");
1524 Value
= ConfigResp
+ StrLen (ConfigResp
);
1526 if (!IsBufferStorage
&& IsString
) {
1528 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1530 TemName
= (CHAR16
*) Src
;
1532 for (; *TemName
!= L
'\0'; TemName
++) {
1533 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1537 // Convert Buffer to Hex String
1539 TemBuffer
= Src
+ StorageWidth
- 1;
1541 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1542 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1547 // Convert to lower char.
1549 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1550 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1551 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1556 // Submit Question Value to Configuration Driver
1558 if (FormSet
->ConfigAccess
!= NULL
) {
1559 Status
= FormSet
->ConfigAccess
->RouteConfig (
1560 FormSet
->ConfigAccess
,
1564 if (EFI_ERROR (Status
)) {
1565 FreePool (ConfigResp
);
1569 FreePool (ConfigResp
);
1572 // Synchronize shadow Buffer
1574 SynchronizeStorage (Storage
);
1582 Perform inconsistent check for a Form.
1584 @param FormSet FormSet data structure.
1585 @param Form Form data structure.
1586 @param Question The Question to be validated.
1587 @param Type Validation type: InConsistent or NoSubmit
1589 @retval EFI_SUCCESS Form validation pass.
1590 @retval other Form validation failed.
1595 IN FORM_BROWSER_FORMSET
*FormSet
,
1596 IN FORM_BROWSER_FORM
*Form
,
1597 IN FORM_BROWSER_STATEMENT
*Question
,
1603 LIST_ENTRY
*ListHead
;
1606 FORM_EXPRESSION
*Expression
;
1608 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1609 ListHead
= &Question
->InconsistentListHead
;
1610 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1611 ListHead
= &Question
->NoSubmitListHead
;
1613 return EFI_UNSUPPORTED
;
1616 Link
= GetFirstNode (ListHead
);
1617 while (!IsNull (ListHead
, Link
)) {
1618 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1621 // Evaluate the expression
1623 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1624 if (EFI_ERROR (Status
)) {
1628 if (Expression
->Result
.Value
.b
) {
1630 // Condition meet, show up error message
1632 if (Expression
->Error
!= 0) {
1633 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1635 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1636 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1640 return EFI_NOT_READY
;
1643 Link
= GetNextNode (ListHead
, Link
);
1651 Perform NoSubmit check for a Form.
1653 @param FormSet FormSet data structure.
1654 @param Form Form data structure.
1656 @retval EFI_SUCCESS Form validation pass.
1657 @retval other Form validation failed.
1662 IN FORM_BROWSER_FORMSET
*FormSet
,
1663 IN FORM_BROWSER_FORM
*Form
1668 FORM_BROWSER_STATEMENT
*Question
;
1670 Link
= GetFirstNode (&Form
->StatementListHead
);
1671 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1672 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1674 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1675 if (EFI_ERROR (Status
)) {
1679 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1689 @param FormSet FormSet data structure.
1690 @param Form Form data structure.
1692 @retval EFI_SUCCESS The function completed successfully.
1697 IN FORM_BROWSER_FORMSET
*FormSet
,
1698 IN FORM_BROWSER_FORM
*Form
1703 EFI_STRING ConfigResp
;
1704 EFI_STRING Progress
;
1705 FORMSET_STORAGE
*Storage
;
1708 // Validate the Form by NoSubmit check
1710 Status
= NoSubmitCheck (FormSet
, Form
);
1711 if (EFI_ERROR (Status
)) {
1716 // Submit Buffer storage or Name/Value storage
1718 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1719 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1720 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1721 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1723 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1728 // Skip if there is no RequestElement
1730 if (Storage
->ElementCount
== 0) {
1735 // Prepare <ConfigResp>
1737 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
1738 if (EFI_ERROR (Status
)) {
1743 // Send <ConfigResp> to Configuration Driver
1745 if (FormSet
->ConfigAccess
!= NULL
) {
1746 Status
= FormSet
->ConfigAccess
->RouteConfig (
1747 FormSet
->ConfigAccess
,
1751 if (EFI_ERROR (Status
)) {
1752 FreePool (ConfigResp
);
1756 FreePool (ConfigResp
);
1759 // Config success, update storage shadow Buffer
1761 SynchronizeStorage (Storage
);
1764 gNvUpdateRequired
= FALSE
;
1771 Reset Question to its default value.
1773 @param FormSet The form set.
1774 @param Form The form.
1775 @param Question The question.
1776 @param DefaultId The Class of the default.
1778 @retval EFI_SUCCESS Question is reset to default value.
1782 GetQuestionDefault (
1783 IN FORM_BROWSER_FORMSET
*FormSet
,
1784 IN FORM_BROWSER_FORM
*Form
,
1785 IN FORM_BROWSER_STATEMENT
*Question
,
1791 QUESTION_DEFAULT
*Default
;
1792 QUESTION_OPTION
*Option
;
1793 EFI_HII_VALUE
*HiiValue
;
1795 EFI_STRING StrValue
;
1797 Status
= EFI_SUCCESS
;
1801 // Statement don't have storage, skip them
1803 if (Question
->QuestionId
== 0) {
1808 // There are three ways to specify default value for a Question:
1809 // 1, use nested EFI_IFR_DEFAULT (highest priority)
1810 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
1811 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
1813 HiiValue
= &Question
->HiiValue
;
1816 // EFI_IFR_DEFAULT has highest priority
1818 if (!IsListEmpty (&Question
->DefaultListHead
)) {
1819 Link
= GetFirstNode (&Question
->DefaultListHead
);
1820 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
1821 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1823 if (Default
->DefaultId
== DefaultId
) {
1824 if (Default
->ValueExpression
!= NULL
) {
1826 // Default is provided by an Expression, evaluate it
1828 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
1829 if (EFI_ERROR (Status
)) {
1833 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1836 // Default value is embedded in EFI_IFR_DEFAULT
1838 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
1841 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1842 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
1843 if (StrValue
== NULL
) {
1844 return EFI_NOT_FOUND
;
1846 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
1852 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
1857 // EFI_ONE_OF_OPTION
1859 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
1860 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1862 // OneOfOption could only provide Standard and Manufacturing default
1864 Link
= GetFirstNode (&Question
->OptionListHead
);
1865 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1866 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1868 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
1869 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
1871 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1876 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1882 // EFI_IFR_CHECKBOX - lowest priority
1884 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
1885 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1887 // Checkbox could only provide Standard and Manufacturing default
1889 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
1890 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
1892 HiiValue
->Value
.b
= TRUE
;
1894 HiiValue
->Value
.b
= FALSE
;
1902 // For Questions without default
1904 switch (Question
->Operand
) {
1905 case EFI_IFR_ONE_OF_OP
:
1907 // Take first oneof option as oneof's default value
1909 if (ValueToOption (Question
, HiiValue
) == NULL
) {
1910 Link
= GetFirstNode (&Question
->OptionListHead
);
1911 if (!IsNull (&Question
->OptionListHead
, Link
)) {
1912 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1913 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1918 case EFI_IFR_ORDERED_LIST_OP
:
1920 // Take option sequence in IFR as ordered list's default value
1923 Link
= GetFirstNode (&Question
->OptionListHead
);
1924 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1925 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1927 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
1930 if (Index
>= Question
->MaxContainers
) {
1934 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1939 Status
= EFI_NOT_FOUND
;
1948 Reset Questions in a Form to their default value.
1950 @param FormSet FormSet data structure.
1951 @param Form The Form which to be reset.
1952 @param DefaultId The Class of the default.
1954 @retval EFI_SUCCESS The function completed successfully.
1958 ExtractFormDefault (
1959 IN FORM_BROWSER_FORMSET
*FormSet
,
1960 IN FORM_BROWSER_FORM
*Form
,
1966 FORM_BROWSER_STATEMENT
*Question
;
1968 Link
= GetFirstNode (&Form
->StatementListHead
);
1969 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1970 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1971 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1974 // If Question is disabled, don't reset it to default
1976 if (Question
->DisableExpression
!= NULL
) {
1977 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
1978 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
1984 // Reset Question to its default value
1986 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
1987 if (EFI_ERROR (Status
)) {
1992 // Synchronize Buffer storage's Edit buffer
1994 if ((Question
->Storage
!= NULL
) &&
1995 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1996 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2005 Initialize Question's Edit copy from Storage.
2007 @param FormSet FormSet data structure.
2008 @param Form Form data structure.
2010 @retval EFI_SUCCESS The function completed successfully.
2015 IN FORM_BROWSER_FORMSET
*FormSet
,
2016 IN FORM_BROWSER_FORM
*Form
2021 FORM_BROWSER_STATEMENT
*Question
;
2023 Link
= GetFirstNode (&Form
->StatementListHead
);
2024 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2025 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2028 // Initialize local copy of Value for each Question
2030 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2031 if (EFI_ERROR (Status
)) {
2035 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2043 Initialize Question's Edit copy from Storage for the whole Formset.
2045 @param FormSet FormSet data structure.
2047 @retval EFI_SUCCESS The function completed successfully.
2052 IN FORM_BROWSER_FORMSET
*FormSet
2057 FORM_BROWSER_FORM
*Form
;
2059 Link
= GetFirstNode (&FormSet
->FormListHead
);
2060 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2061 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2064 // Initialize local copy of Value for each Form
2066 Status
= LoadFormConfig (FormSet
, Form
);
2067 if (EFI_ERROR (Status
)) {
2071 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2079 Fill storage's edit copy with settings requested from Configuration Driver.
2081 @param FormSet FormSet data structure.
2082 @param Storage Buffer Storage.
2084 @retval EFI_SUCCESS The function completed successfully.
2089 IN FORM_BROWSER_FORMSET
*FormSet
,
2090 IN FORMSET_STORAGE
*Storage
2094 EFI_STRING Progress
;
2098 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2102 if (FormSet
->ConfigAccess
== NULL
) {
2103 return EFI_NOT_FOUND
;
2106 if (Storage
->ElementCount
== 0) {
2108 // Skip if there is no RequestElement
2114 // Request current settings from Configuration Driver
2116 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2117 FormSet
->ConfigAccess
,
2118 Storage
->ConfigRequest
,
2122 if (EFI_ERROR (Status
)) {
2127 // Convert Result from <ConfigAltResp> to <ConfigResp>
2129 StrPtr
= StrStr (Result
, L
"ALTCFG");
2130 if (StrPtr
!= NULL
) {
2134 Status
= ConfigRespToStorage (Storage
, Result
);
2141 Copy uncommitted data from source Storage to destination Storage.
2143 @param Dst Target Storage for uncommitted data.
2144 @param Src Source Storage for uncommitted data.
2146 @retval EFI_SUCCESS The function completed successfully.
2147 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2152 IN OUT FORMSET_STORAGE
*Dst
,
2153 IN FORMSET_STORAGE
*Src
2157 NAME_VALUE_NODE
*Node
;
2159 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2160 return EFI_INVALID_PARAMETER
;
2163 switch (Src
->Type
) {
2164 case EFI_HII_VARSTORE_BUFFER
:
2165 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
2168 case EFI_HII_VARSTORE_NAME_VALUE
:
2169 Link
= GetFirstNode (&Src
->NameValueListHead
);
2170 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
2171 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2173 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
);
2175 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
2179 case EFI_HII_VARSTORE_EFI_VARIABLE
:
2189 Get current setting of Questions.
2191 @param FormSet FormSet data structure.
2193 @retval EFI_SUCCESS The function completed successfully.
2197 InitializeCurrentSetting (
2198 IN OUT FORM_BROWSER_FORMSET
*FormSet
2203 FORMSET_STORAGE
*Storage
;
2204 FORMSET_STORAGE
*StorageSrc
;
2205 FORMSET_STORAGE
*OldStorage
;
2206 FORM_BROWSER_FORM
*Form
;
2210 // Extract default from IFR binary
2212 Link
= GetFirstNode (&FormSet
->FormListHead
);
2213 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2214 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2216 Status
= ExtractFormDefault (FormSet
, Form
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2218 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2222 // Request current settings from Configuration Driver
2224 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2225 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2226 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2229 if (gOldFormSet
!= NULL
) {
2231 // Try to find the Storage in backup formset gOldFormSet
2233 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
2234 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
2235 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
2237 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
2238 OldStorage
= StorageSrc
;
2242 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
2246 if (OldStorage
== NULL
) {
2248 // Storage is not found in backup formset, request it from ConfigDriver
2250 Status
= LoadStorage (FormSet
, Storage
);
2253 // Storage found in backup formset, use it
2255 Status
= CopyStorage (Storage
, OldStorage
);
2259 // Now Edit Buffer is filled with default values(lower priority) and current
2260 // settings(higher priority), sychronize it to shadow Buffer
2262 if (!EFI_ERROR (Status
)) {
2263 SynchronizeStorage (Storage
);
2266 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2274 Fetch the Ifr binary data of a FormSet.
2276 @param Handle PackageList Handle
2277 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2278 specified (NULL or zero GUID), take the first
2279 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2280 found in package list.
2281 On output, GUID of the formset found(if not NULL).
2282 @param BinaryLength The length of the FormSet IFR binary.
2283 @param BinaryData The buffer designed to receive the FormSet.
2285 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
2286 BufferLength was updated.
2287 @retval EFI_INVALID_PARAMETER The handle is unknown.
2288 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
2289 be found with the requested FormId.
2294 IN EFI_HII_HANDLE Handle
,
2295 IN OUT EFI_GUID
*FormSetGuid
,
2296 OUT UINTN
*BinaryLength
,
2297 OUT UINT8
**BinaryData
2301 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2307 UINT32 PackageListLength
;
2308 EFI_HII_PACKAGE_HEADER PackageHeader
;
2310 UINT8 NumberOfClassGuid
;
2311 BOOLEAN ClassGuidMatch
;
2312 EFI_GUID
*ClassGuid
;
2313 EFI_GUID
*ComparingGuid
;
2317 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
2320 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
2322 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
2323 ComparingGuid
= &gEfiHiiPlatformSetupFormsetGuid
;
2325 ComparingGuid
= FormSetGuid
;
2329 // Get HII PackageList
2332 HiiPackageList
= NULL
;
2333 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2334 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2335 HiiPackageList
= AllocatePool (BufferSize
);
2336 ASSERT (HiiPackageList
!= NULL
);
2338 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2340 if (EFI_ERROR (Status
)) {
2343 ASSERT (HiiPackageList
!= NULL
);
2346 // Get Form package from this HII package List
2348 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2350 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
2352 ClassGuidMatch
= FALSE
;
2353 while (Offset
< PackageListLength
) {
2354 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
2355 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2357 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
2359 // Search FormSet in this Form Package
2361 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
2362 while (Offset2
< PackageHeader
.Length
) {
2363 OpCodeData
= Package
+ Offset2
;
2365 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
2367 // Try to compare against formset GUID
2369 if (CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2374 // Try to compare against formset class GUID
2376 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2377 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
2378 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
2379 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
2380 ClassGuidMatch
= TRUE
;
2384 if (ClassGuidMatch
) {
2389 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
2392 if (Offset2
< PackageHeader
.Length
) {
2394 // Target formset found
2400 Offset
+= PackageHeader
.Length
;
2403 if (Offset
>= PackageListLength
) {
2405 // Form package not found in this Package List
2407 FreePool (HiiPackageList
);
2408 return EFI_NOT_FOUND
;
2411 if (ClassGuidMatch
&& (FormSetGuid
!= NULL
)) {
2413 // Return the FormSet GUID
2415 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2419 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
2420 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
2421 // of the Form Package.
2423 *BinaryLength
= PackageHeader
.Length
- Offset2
;
2424 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
2426 FreePool (HiiPackageList
);
2428 if (*BinaryData
== NULL
) {
2429 return EFI_OUT_OF_RESOURCES
;
2437 Initialize the internal data structure of a FormSet.
2439 @param Handle PackageList Handle
2440 @param FormSetGuid On input, GUID or class GUID of a formset. If not
2441 specified (NULL or zero GUID), take the first
2442 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
2443 found in package list.
2444 On output, GUID of the formset found(if not NULL).
2445 @param FormSet FormSet data structure.
2447 @retval EFI_SUCCESS The function completed successfully.
2448 @retval EFI_NOT_FOUND The specified FormSet could not be found.
2453 IN EFI_HII_HANDLE Handle
,
2454 IN OUT EFI_GUID
*FormSetGuid
,
2455 OUT FORM_BROWSER_FORMSET
*FormSet
2459 EFI_HANDLE DriverHandle
;
2462 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
2463 if (EFI_ERROR (Status
)) {
2467 FormSet
->HiiHandle
= Handle
;
2468 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
2471 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
2473 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
2474 if (EFI_ERROR (Status
)) {
2477 FormSet
->DriverHandle
= DriverHandle
;
2478 Status
= gBS
->HandleProtocol (
2480 &gEfiHiiConfigAccessProtocolGuid
,
2481 (VOID
**) &FormSet
->ConfigAccess
2483 if (EFI_ERROR (Status
)) {
2485 // Configuration Driver don't attach ConfigAccess protocol to its HII package
2486 // list, then there will be no configuration action required
2488 FormSet
->ConfigAccess
= NULL
;
2492 // Parse the IFR binary OpCodes
2494 Status
= ParseOpCodes (FormSet
);
2495 if (EFI_ERROR (Status
)) {
2499 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
2500 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
2501 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
2502 gFrontPageHandle
= FormSet
->HiiHandle
;
2506 // Match GUID to find out the function key setting. If match fail, use the default setting.
2508 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
2509 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
2511 // Update the function key setting.
2513 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
2515 // Function key prompt can not be displayed if the function key has been disabled.
2517 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2518 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2521 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2522 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2532 Save globals used by previous call to SendForm(). SendForm() may be called from
2533 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
2534 So, save globals of previous call to SendForm() and restore them upon exit.
2538 SaveBrowserContext (
2542 BROWSER_CONTEXT
*Context
;
2544 gBrowserContextCount
++;
2545 if (gBrowserContextCount
== 1) {
2547 // This is not reentry of SendForm(), no context to save
2552 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
2553 ASSERT (Context
!= NULL
);
2555 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
2558 // Save FormBrowser context
2560 Context
->BannerData
= gBannerData
;
2561 Context
->ClassOfVfr
= gClassOfVfr
;
2562 Context
->FunctionKeySetting
= gFunctionKeySetting
;
2563 Context
->ResetRequired
= gResetRequired
;
2564 Context
->NvUpdateRequired
= gNvUpdateRequired
;
2565 Context
->Direction
= gDirection
;
2566 Context
->FunctionNineString
= gFunctionNineString
;
2567 Context
->FunctionTenString
= gFunctionTenString
;
2568 Context
->EnterString
= gEnterString
;
2569 Context
->EnterCommitString
= gEnterCommitString
;
2570 Context
->EnterEscapeString
= gEnterEscapeString
;
2571 Context
->EscapeString
= gEscapeString
;
2572 Context
->SaveFailed
= gSaveFailed
;
2573 Context
->MoveHighlight
= gMoveHighlight
;
2574 Context
->MakeSelection
= gMakeSelection
;
2575 Context
->DecNumericInput
= gDecNumericInput
;
2576 Context
->HexNumericInput
= gHexNumericInput
;
2577 Context
->ToggleCheckBox
= gToggleCheckBox
;
2578 Context
->PromptForData
= gPromptForData
;
2579 Context
->PromptForPassword
= gPromptForPassword
;
2580 Context
->PromptForNewPassword
= gPromptForNewPassword
;
2581 Context
->ConfirmPassword
= gConfirmPassword
;
2582 Context
->ConfirmError
= gConfirmError
;
2583 Context
->PassowordInvalid
= gPassowordInvalid
;
2584 Context
->PressEnter
= gPressEnter
;
2585 Context
->EmptyString
= gEmptyString
;
2586 Context
->AreYouSure
= gAreYouSure
;
2587 Context
->YesResponse
= gYesResponse
;
2588 Context
->NoResponse
= gNoResponse
;
2589 Context
->MiniString
= gMiniString
;
2590 Context
->PlusString
= gPlusString
;
2591 Context
->MinusString
= gMinusString
;
2592 Context
->AdjustNumber
= gAdjustNumber
;
2593 Context
->SaveChanges
= gSaveChanges
;
2594 Context
->OptionMismatch
= gOptionMismatch
;
2595 Context
->PromptBlockWidth
= gPromptBlockWidth
;
2596 Context
->OptionBlockWidth
= gOptionBlockWidth
;
2597 Context
->HelpBlockWidth
= gHelpBlockWidth
;
2598 Context
->OldFormSet
= gOldFormSet
;
2599 Context
->MenuRefreshHead
= gMenuRefreshHead
;
2601 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
2602 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
2605 // Insert to FormBrowser context list
2607 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
2612 Restore globals used by previous call to SendForm().
2616 RestoreBrowserContext (
2621 BROWSER_CONTEXT
*Context
;
2623 ASSERT (gBrowserContextCount
!= 0);
2624 gBrowserContextCount
--;
2625 if (gBrowserContextCount
== 0) {
2627 // This is not reentry of SendForm(), no context to restore
2632 ASSERT (!IsListEmpty (&gBrowserContextList
));
2634 Link
= GetFirstNode (&gBrowserContextList
);
2635 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
2638 // Restore FormBrowser context
2640 gBannerData
= Context
->BannerData
;
2641 gClassOfVfr
= Context
->ClassOfVfr
;
2642 gFunctionKeySetting
= Context
->FunctionKeySetting
;
2643 gResetRequired
= Context
->ResetRequired
;
2644 gNvUpdateRequired
= Context
->NvUpdateRequired
;
2645 gDirection
= Context
->Direction
;
2646 gFunctionNineString
= Context
->FunctionNineString
;
2647 gFunctionTenString
= Context
->FunctionTenString
;
2648 gEnterString
= Context
->EnterString
;
2649 gEnterCommitString
= Context
->EnterCommitString
;
2650 gEnterEscapeString
= Context
->EnterEscapeString
;
2651 gEscapeString
= Context
->EscapeString
;
2652 gSaveFailed
= Context
->SaveFailed
;
2653 gMoveHighlight
= Context
->MoveHighlight
;
2654 gMakeSelection
= Context
->MakeSelection
;
2655 gDecNumericInput
= Context
->DecNumericInput
;
2656 gHexNumericInput
= Context
->HexNumericInput
;
2657 gToggleCheckBox
= Context
->ToggleCheckBox
;
2658 gPromptForData
= Context
->PromptForData
;
2659 gPromptForPassword
= Context
->PromptForPassword
;
2660 gPromptForNewPassword
= Context
->PromptForNewPassword
;
2661 gConfirmPassword
= Context
->ConfirmPassword
;
2662 gConfirmError
= Context
->ConfirmError
;
2663 gPassowordInvalid
= Context
->PassowordInvalid
;
2664 gPressEnter
= Context
->PressEnter
;
2665 gEmptyString
= Context
->EmptyString
;
2666 gAreYouSure
= Context
->AreYouSure
;
2667 gYesResponse
= Context
->YesResponse
;
2668 gNoResponse
= Context
->NoResponse
;
2669 gMiniString
= Context
->MiniString
;
2670 gPlusString
= Context
->PlusString
;
2671 gMinusString
= Context
->MinusString
;
2672 gAdjustNumber
= Context
->AdjustNumber
;
2673 gSaveChanges
= Context
->SaveChanges
;
2674 gOptionMismatch
= Context
->OptionMismatch
;
2675 gPromptBlockWidth
= Context
->PromptBlockWidth
;
2676 gOptionBlockWidth
= Context
->OptionBlockWidth
;
2677 gHelpBlockWidth
= Context
->HelpBlockWidth
;
2678 gOldFormSet
= Context
->OldFormSet
;
2679 gMenuRefreshHead
= Context
->MenuRefreshHead
;
2681 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
2682 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
2685 // Remove from FormBrowser context list
2687 RemoveEntryList (&Context
->Link
);
2688 gBS
->FreePool (Context
);