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
;
78 CHAR16
*mUnknownString
= L
"!";
80 CHAR16 gPromptBlockWidth
;
81 CHAR16 gOptionBlockWidth
;
82 CHAR16 gHelpBlockWidth
;
84 EFI_GUID gZeroGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
85 EFI_GUID gSetupBrowserGuid
= {
86 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
89 FORM_BROWSER_FORMSET
*gOldFormSet
;
91 FUNCTIION_KEY_SETTING gFunctionKeySettingTable
[] = {
111 NONE_FUNCTION_KEY_SETTING
132 NONE_FUNCTION_KEY_SETTING
153 NONE_FUNCTION_KEY_SETTING
156 // BMM File Explorer FormSet.
174 NONE_FUNCTION_KEY_SETTING
179 This is the routine which an external caller uses to direct the browser
180 where to obtain it's information.
183 @param This The Form Browser protocol instanse.
184 @param Handles A pointer to an array of Handles. If HandleCount > 1 we
185 display a list of the formsets for the handles specified.
186 @param HandleCount The number of Handles specified in Handle.
187 @param FormSetGuid This field points to the EFI_GUID which must match the Guid
188 field in the EFI_IFR_FORM_SET op-code for the specified
189 forms-based package. If FormSetGuid is NULL, then this
190 function will display the first found forms package.
191 @param FormId This field specifies which EFI_IFR_FORM to render as the first
192 displayable page. If this field has a value of 0x0000, then
193 the forms browser will render the specified forms in their encoded order.
194 @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in
196 @param ActionRequest Points to the action recommended by the form.
198 @retval EFI_SUCCESS The function completed successfully.
199 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
200 @retval EFI_NOT_FOUND No valid forms could be found to display.
206 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
207 IN EFI_HII_HANDLE
*Handles
,
208 IN UINTN HandleCount
,
209 IN EFI_GUID
*FormSetGuid
, OPTIONAL
210 IN UINT16 FormId
, OPTIONAL
211 IN CONST EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
212 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest OPTIONAL
216 UI_MENU_SELECTION
*Selection
;
218 FORM_BROWSER_FORMSET
*FormSet
;
221 // Save globals used by SendForm()
223 SaveBrowserContext ();
225 Status
= EFI_SUCCESS
;
226 ZeroMem (&gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
229 // Seed the dimensions in the global
231 gST
->ConOut
->QueryMode (
233 gST
->ConOut
->Mode
->Mode
,
234 &gScreenDimensions
.RightColumn
,
235 &gScreenDimensions
.BottomRow
238 if (ScreenDimensions
!= NULL
) {
240 // Check local dimension vs. global dimension.
242 if ((gScreenDimensions
.RightColumn
< ScreenDimensions
->RightColumn
) ||
243 (gScreenDimensions
.BottomRow
< ScreenDimensions
->BottomRow
)
245 Status
= EFI_INVALID_PARAMETER
;
249 // Local dimension validation.
251 if ((ScreenDimensions
->RightColumn
> ScreenDimensions
->LeftColumn
) &&
252 (ScreenDimensions
->BottomRow
> ScreenDimensions
->TopRow
) &&
253 ((ScreenDimensions
->RightColumn
- ScreenDimensions
->LeftColumn
) > 2) &&
255 (ScreenDimensions
->BottomRow
- ScreenDimensions
->TopRow
) > STATUS_BAR_HEIGHT
+
256 SCROLL_ARROW_HEIGHT
*
258 FRONT_PAGE_HEADER_HEIGHT
+
263 CopyMem (&gScreenDimensions
, (VOID
*) ScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
265 Status
= EFI_INVALID_PARAMETER
;
271 gOptionBlockWidth
= (CHAR16
) ((gScreenDimensions
.RightColumn
- gScreenDimensions
.LeftColumn
) / 3);
272 gHelpBlockWidth
= gOptionBlockWidth
;
273 gPromptBlockWidth
= gOptionBlockWidth
;
276 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
278 InitializeBrowserStrings ();
280 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
281 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
284 // Ensure we are in Text mode
286 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
288 for (Index
= 0; Index
< HandleCount
; Index
++) {
289 Selection
= AllocateZeroPool (sizeof (UI_MENU_SELECTION
));
290 ASSERT (Selection
!= NULL
);
292 Selection
->Handle
= Handles
[Index
];
293 if (FormSetGuid
!= NULL
) {
294 CopyMem (&Selection
->FormSetGuid
, FormSetGuid
, sizeof (EFI_GUID
));
295 Selection
->FormId
= FormId
;
299 gNvUpdateRequired
= FALSE
;
302 FormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
303 ASSERT (FormSet
!= NULL
);
306 // Initialize internal data structures of FormSet
308 Status
= InitializeFormSet (Selection
->Handle
, &Selection
->FormSetGuid
, FormSet
);
309 if (EFI_ERROR (Status
) || IsListEmpty (&FormSet
->FormListHead
)) {
310 DestroyFormSet (FormSet
);
313 Selection
->FormSet
= FormSet
;
316 // Display this formset
318 gCurrentSelection
= Selection
;
320 Status
= SetupBrowser (Selection
);
322 gCurrentSelection
= NULL
;
324 if (EFI_ERROR (Status
)) {
328 } while (Selection
->Action
== UI_ACTION_REFRESH_FORMSET
);
330 if (gOldFormSet
!= NULL
) {
331 DestroyFormSet (gOldFormSet
);
335 FreePool (Selection
);
338 if (ActionRequest
!= NULL
) {
339 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
340 if (gResetRequired
) {
341 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
345 FreeBrowserStrings ();
347 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
348 gST
->ConOut
->ClearScreen (gST
->ConOut
);
352 // Restore globals used by SendForm()
354 RestoreBrowserContext ();
361 This function is called by a callback handler to retrieve uncommitted state
362 data from the browser.
364 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
366 @param ResultsDataSize A pointer to the size of the buffer associated
368 @param ResultsData A string returned from an IFR browser or
369 equivalent. The results string will have no
370 routing information in them.
371 @param RetrieveData A BOOLEAN field which allows an agent to retrieve
372 (if RetrieveData = TRUE) data from the uncommitted
373 browser state information or set (if RetrieveData
374 = FALSE) data in the uncommitted browser state
376 @param VariableGuid An optional field to indicate the target variable
378 @param VariableName An optional field to indicate the target
379 human-readable variable name.
381 @retval EFI_SUCCESS The results have been distributed or are awaiting
383 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to
384 contain the results data.
390 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
391 IN OUT UINTN
*ResultsDataSize
,
392 IN OUT EFI_STRING ResultsData
,
393 IN BOOLEAN RetrieveData
,
394 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
395 IN CONST CHAR16
*VariableName OPTIONAL
400 FORMSET_STORAGE
*Storage
;
401 FORM_BROWSER_FORMSET
*FormSet
;
408 if (ResultsDataSize
== NULL
|| ResultsData
== NULL
) {
409 return EFI_INVALID_PARAMETER
;
412 if (gCurrentSelection
== NULL
) {
413 return EFI_NOT_READY
;
418 FormSet
= gCurrentSelection
->FormSet
;
421 // Find target storage
423 Link
= GetFirstNode (&FormSet
->StorageListHead
);
424 if (IsNull (&FormSet
->StorageListHead
, Link
)) {
425 return EFI_UNSUPPORTED
;
428 if (VariableGuid
!= NULL
) {
430 // Try to find target storage
433 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
434 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
435 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
437 if (CompareGuid (&Storage
->Guid
, (EFI_GUID
*) VariableGuid
)) {
438 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
440 // Buffer storage require both GUID and Name
442 if (VariableName
== NULL
) {
443 return EFI_NOT_FOUND
;
446 if (StrCmp (Storage
->Name
, (CHAR16
*) VariableName
) != 0) {
456 return EFI_NOT_FOUND
;
460 // GUID/Name is not specified, take the first storage in FormSet
462 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
467 // Skip if there is no RequestElement
469 if (Storage
->ElementCount
== 0) {
474 // Generate <ConfigResp>
476 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
477 if (EFI_ERROR (Status
)) {
482 // Skip <ConfigHdr> and '&' to point to <ConfigBody>
484 StrPtr
= ConfigResp
+ StrLen (Storage
->ConfigHdr
) + 1;
486 BufferSize
= StrSize (StrPtr
);
487 if (*ResultsDataSize
< BufferSize
) {
488 *ResultsDataSize
= BufferSize
;
490 FreePool (ConfigResp
);
491 return EFI_BUFFER_TOO_SMALL
;
494 *ResultsDataSize
= BufferSize
;
495 CopyMem (ResultsData
, StrPtr
, BufferSize
);
497 FreePool (ConfigResp
);
500 // Prepare <ConfigResp>
502 TmpSize
= StrLen (ResultsData
);
503 BufferSize
= (TmpSize
+ StrLen (Storage
->ConfigHdr
) + 2) * sizeof (CHAR16
);
504 ConfigResp
= AllocateZeroPool (BufferSize
);
505 ASSERT (ConfigResp
!= NULL
);
507 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
508 StrCat (ConfigResp
, L
"&");
509 StrCat (ConfigResp
, ResultsData
);
512 // Update Browser uncommited data
514 Status
= ConfigRespToStorage (Storage
, ConfigResp
);
515 if (EFI_ERROR (Status
)) {
525 Initialize Setup Browser driver.
527 @param ImageHandle The image handle.
528 @param SystemTable The system table.
530 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
531 @return Other value if failed to initialize the Setup Browser module.
537 IN EFI_HANDLE ImageHandle
,
538 IN EFI_SYSTEM_TABLE
*SystemTable
544 // Locate required Hii relative protocols
546 Status
= gBS
->LocateProtocol (
547 &gEfiHiiDatabaseProtocolGuid
,
549 (VOID
**) &mHiiDatabase
551 ASSERT_EFI_ERROR (Status
);
553 Status
= gBS
->LocateProtocol (
554 &gEfiHiiStringProtocolGuid
,
556 (VOID
**) &mHiiString
558 ASSERT_EFI_ERROR (Status
);
560 Status
= gBS
->LocateProtocol (
561 &gEfiHiiConfigRoutingProtocolGuid
,
563 (VOID
**) &mHiiConfigRouting
565 ASSERT_EFI_ERROR (Status
);
568 // Publish our HII data
570 gHiiHandle
= HiiAddPackages (
576 ASSERT (gHiiHandle
!= NULL
);
579 // Initialize Driver private data
581 gBannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
582 ASSERT (gBannerData
!= NULL
);
585 // Install FormBrowser2 protocol
587 mPrivateData
.Handle
= NULL
;
588 Status
= gBS
->InstallProtocolInterface (
589 &mPrivateData
.Handle
,
590 &gEfiFormBrowser2ProtocolGuid
,
591 EFI_NATIVE_INTERFACE
,
592 &mPrivateData
.FormBrowser2
594 ASSERT_EFI_ERROR (Status
);
601 Create a new string in HII Package List.
603 @param String The String to be added
604 @param HiiHandle The package list in the HII database to insert the
607 @return The output string.
613 IN EFI_HII_HANDLE HiiHandle
616 EFI_STRING_ID StringId
;
618 StringId
= HiiSetString (HiiHandle
, 0, String
, NULL
);
619 ASSERT (StringId
!= 0);
626 Delete a string from HII Package List.
628 @param StringId Id of the string in HII database.
629 @param HiiHandle The HII package list handle.
631 @retval EFI_SUCCESS The string was deleted successfully.
636 IN EFI_STRING_ID StringId
,
637 IN EFI_HII_HANDLE HiiHandle
642 NullChar
= CHAR_NULL
;
643 HiiSetString (HiiHandle
, StringId
, &NullChar
, NULL
);
649 Get the string based on the StringId and HII Package List Handle.
651 @param Token The String's ID.
652 @param HiiHandle The package list in the HII database to search for
653 the specified string.
655 @return The output string.
660 IN EFI_STRING_ID Token
,
661 IN EFI_HII_HANDLE HiiHandle
666 String
= HiiGetString (HiiHandle
, Token
, NULL
);
667 if (String
== NULL
) {
668 String
= AllocateCopyPool (sizeof (mUnknownString
), mUnknownString
);
669 ASSERT (String
!= NULL
);
671 return (CHAR16
*) String
;
676 Allocate new memory and then copy the Unicode string Source to Destination.
678 @param Dest Location to copy string
679 @param Src String to copy
684 IN OUT CHAR16
**Dest
,
691 *Dest
= AllocateCopyPool (StrSize (Src
), Src
);
692 ASSERT (*Dest
!= NULL
);
697 Allocate new memory and concatinate Source on the end of Destination.
699 @param Dest String to added to the end of.
700 @param Src String to concatinate.
705 IN OUT CHAR16
**Dest
,
713 NewStringCpy (Dest
, Src
);
717 TmpSize
= StrSize (*Dest
);
718 NewString
= AllocateZeroPool (TmpSize
+ StrSize (Src
) - 1);
719 ASSERT (NewString
!= NULL
);
721 StrCpy (NewString
, *Dest
);
722 StrCat (NewString
, Src
);
730 Synchronize Storage's Edit copy to Shadow copy.
732 @param Storage The Storage to be synchronized.
737 IN FORMSET_STORAGE
*Storage
741 NAME_VALUE_NODE
*Node
;
743 switch (Storage
->Type
) {
744 case EFI_HII_VARSTORE_BUFFER
:
745 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
748 case EFI_HII_VARSTORE_NAME_VALUE
:
749 Link
= GetFirstNode (&Storage
->NameValueListHead
);
750 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
751 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
753 NewStringCpy (&Node
->Value
, Node
->EditValue
);
755 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
759 case EFI_HII_VARSTORE_EFI_VARIABLE
:
767 Get Value for given Name from a NameValue Storage.
769 @param Storage The NameValue Storage.
770 @param Name The Name.
771 @param Value The retured Value.
773 @retval EFI_SUCCESS Value found for given Name.
774 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
779 IN FORMSET_STORAGE
*Storage
,
781 IN OUT CHAR16
**Value
785 NAME_VALUE_NODE
*Node
;
789 Link
= GetFirstNode (&Storage
->NameValueListHead
);
790 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
791 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
793 if (StrCmp (Name
, Node
->Name
) == 0) {
794 NewStringCpy (Value
, Node
->EditValue
);
798 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
801 return EFI_NOT_FOUND
;
806 Set Value of given Name in a NameValue Storage.
808 @param Storage The NameValue Storage.
809 @param Name The Name.
810 @param Value The Value to set.
812 @retval EFI_SUCCESS Value found for given Name.
813 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
818 IN FORMSET_STORAGE
*Storage
,
824 NAME_VALUE_NODE
*Node
;
826 Link
= GetFirstNode (&Storage
->NameValueListHead
);
827 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
828 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
830 if (StrCmp (Name
, Node
->Name
) == 0) {
831 if (Node
->EditValue
!= NULL
) {
832 FreePool (Node
->EditValue
);
834 Node
->EditValue
= AllocateCopyPool (StrSize (Value
), Value
);
835 ASSERT (Node
->EditValue
!= NULL
);
839 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
842 return EFI_NOT_FOUND
;
847 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
849 @param Storage The Storage to be conveted.
850 @param ConfigResp The returned <ConfigResp>.
852 @retval EFI_SUCCESS Convert success.
853 @retval EFI_INVALID_PARAMETER Incorrect storage type.
857 StorageToConfigResp (
858 IN FORMSET_STORAGE
*Storage
,
859 IN CHAR16
**ConfigResp
865 NAME_VALUE_NODE
*Node
;
867 Status
= EFI_SUCCESS
;
869 switch (Storage
->Type
) {
870 case EFI_HII_VARSTORE_BUFFER
:
871 Status
= mHiiConfigRouting
->BlockToConfig (
873 Storage
->ConfigRequest
,
881 case EFI_HII_VARSTORE_NAME_VALUE
:
883 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
885 Link
= GetFirstNode (&Storage
->NameValueListHead
);
886 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
887 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
889 NewStringCat (ConfigResp
, L
"&");
890 NewStringCat (ConfigResp
, Node
->Name
);
891 NewStringCat (ConfigResp
, L
"=");
892 NewStringCat (ConfigResp
, Node
->EditValue
);
894 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
898 case EFI_HII_VARSTORE_EFI_VARIABLE
:
900 Status
= EFI_INVALID_PARAMETER
;
909 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
911 @param Storage The Storage to receive the settings.
912 @param ConfigResp The <ConfigResp> to be converted.
914 @retval EFI_SUCCESS Convert success.
915 @retval EFI_INVALID_PARAMETER Incorrect storage type.
919 ConfigRespToStorage (
920 IN FORMSET_STORAGE
*Storage
,
921 IN CHAR16
*ConfigResp
931 Status
= EFI_SUCCESS
;
933 switch (Storage
->Type
) {
934 case EFI_HII_VARSTORE_BUFFER
:
935 BufferSize
= Storage
->Size
;
936 Status
= mHiiConfigRouting
->ConfigToBlock (
945 case EFI_HII_VARSTORE_NAME_VALUE
:
946 StrPtr
= StrStr (ConfigResp
, L
"&");
947 while (StrPtr
!= NULL
) {
953 StrPtr
= StrStr (StrPtr
, L
"=");
954 if (StrPtr
== NULL
) {
964 StrPtr
= StrStr (StrPtr
, L
"&");
965 if (StrPtr
!= NULL
) {
968 SetValueByName (Storage
, Name
, Value
);
972 case EFI_HII_VARSTORE_EFI_VARIABLE
:
974 Status
= EFI_INVALID_PARAMETER
;
983 Get Question's current Value.
985 @param FormSet FormSet data structure.
986 @param Form Form data structure.
987 @param Question Question to be initialized.
988 @param Cached TRUE: get from Edit copy FALSE: get from original
991 @retval EFI_SUCCESS The function completed successfully.
996 IN FORM_BROWSER_FORMSET
*FormSet
,
997 IN FORM_BROWSER_FORM
*Form
,
998 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1008 FORMSET_STORAGE
*Storage
;
1009 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1010 CHAR16
*ConfigRequest
;
1018 BOOLEAN IsBufferStorage
;
1023 Status
= EFI_SUCCESS
;
1026 // Statement don't have storage, skip them
1028 if (Question
->QuestionId
== 0) {
1033 // Question value is provided by an Expression, evaluate it
1035 if (Question
->ValueExpression
!= NULL
) {
1036 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1037 if (!EFI_ERROR (Status
)) {
1038 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1044 // Question value is provided by RTC
1046 Storage
= Question
->Storage
;
1047 QuestionValue
= &Question
->HiiValue
.Value
;
1048 if (Storage
== NULL
) {
1050 // It's a Question without storage, or RTC date/time
1052 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1054 // Date and time define the same Flags bit
1056 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1057 case QF_DATE_STORAGE_TIME
:
1058 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1061 case QF_DATE_STORAGE_WAKEUP
:
1062 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1065 case QF_DATE_STORAGE_NORMAL
:
1068 // For date/time without storage
1073 if (EFI_ERROR (Status
)) {
1077 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1078 QuestionValue
->date
.Year
= EfiTime
.Year
;
1079 QuestionValue
->date
.Month
= EfiTime
.Month
;
1080 QuestionValue
->date
.Day
= EfiTime
.Day
;
1082 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1083 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1084 QuestionValue
->time
.Second
= EfiTime
.Second
;
1092 // Question value is provided by EFI variable
1094 StorageWidth
= Question
->StorageWidth
;
1095 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1096 if (Question
->BufferValue
!= NULL
) {
1097 Dst
= Question
->BufferValue
;
1099 Dst
= (UINT8
*) QuestionValue
;
1102 Status
= gRT
->GetVariable (
1103 Question
->VariableName
,
1110 // Always return success, even this EFI variable doesn't exist
1116 // Question Value is provided by Buffer Storage or NameValue Storage
1118 if (Question
->BufferValue
!= NULL
) {
1120 // This Question is password or orderedlist
1122 Dst
= Question
->BufferValue
;
1125 // Other type of Questions
1127 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1130 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1131 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1133 if (IsBufferStorage
) {
1135 // Copy from storage Edit buffer
1137 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1139 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1140 if (EFI_ERROR (Status
)) {
1144 LengthStr
= StrLen (Value
);
1145 Status
= EFI_SUCCESS
;
1148 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1149 // Add string tail char L'\0' into Length
1151 Length
= StorageWidth
+ sizeof (CHAR16
);
1152 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1153 Status
= EFI_BUFFER_TOO_SMALL
;
1155 StringPtr
= (CHAR16
*) Dst
;
1156 ZeroMem (TemStr
, sizeof (TemStr
));
1157 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1158 StrnCpy (TemStr
, Value
+ Index
, 4);
1159 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1162 // Add tailing L'\0' character
1164 StringPtr
[Index
/4] = L
'\0';
1167 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1168 Status
= EFI_BUFFER_TOO_SMALL
;
1170 ZeroMem (TemStr
, sizeof (TemStr
));
1171 for (Index
= 0; Index
< LengthStr
; Index
++) {
1172 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1173 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1174 if ((Index
& 1) == 0) {
1175 Dst
[Index
/2] = DigitUint8
;
1177 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1187 // Request current settings from Configuration Driver
1189 if (FormSet
->ConfigAccess
== NULL
) {
1190 return EFI_NOT_FOUND
;
1194 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1195 // <ConfigHdr> + "&" + <VariableName>
1197 if (IsBufferStorage
) {
1198 Length
= StrLen (Storage
->ConfigHdr
);
1199 Length
+= StrLen (Question
->BlockName
);
1201 Length
= StrLen (Storage
->ConfigHdr
);
1202 Length
+= StrLen (Question
->VariableName
) + 1;
1204 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1205 ASSERT (ConfigRequest
!= NULL
);
1207 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1208 if (IsBufferStorage
) {
1209 StrCat (ConfigRequest
, Question
->BlockName
);
1211 StrCat (ConfigRequest
, L
"&");
1212 StrCat (ConfigRequest
, Question
->VariableName
);
1215 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1216 FormSet
->ConfigAccess
,
1221 if (EFI_ERROR (Status
)) {
1226 // Skip <ConfigRequest>
1228 Value
= Result
+ Length
;
1229 if (IsBufferStorage
) {
1235 if (*Value
!= '=') {
1237 return EFI_NOT_FOUND
;
1240 // Skip '=', point to value
1245 // Suppress <AltResp> if any
1248 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1253 LengthStr
= StrLen (Value
);
1254 Status
= EFI_SUCCESS
;
1255 if (!IsBufferStorage
&& IsString
) {
1257 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1258 // Add string tail char L'\0' into Length
1260 Length
= StorageWidth
+ sizeof (CHAR16
);
1261 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1262 Status
= EFI_BUFFER_TOO_SMALL
;
1264 StringPtr
= (CHAR16
*) Dst
;
1265 ZeroMem (TemStr
, sizeof (TemStr
));
1266 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1267 StrnCpy (TemStr
, Value
+ Index
, 4);
1268 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1271 // Add tailing L'\0' character
1273 StringPtr
[Index
/4] = L
'\0';
1276 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1277 Status
= EFI_BUFFER_TOO_SMALL
;
1279 ZeroMem (TemStr
, sizeof (TemStr
));
1280 for (Index
= 0; Index
< LengthStr
; Index
++) {
1281 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1282 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1283 if ((Index
& 1) == 0) {
1284 Dst
[Index
/2] = DigitUint8
;
1286 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1292 if (EFI_ERROR (Status
)) {
1298 // Synchronize Edit Buffer
1300 if (IsBufferStorage
) {
1301 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1303 SetValueByName (Storage
, Question
->VariableName
, Value
);
1314 Save Question Value to edit copy(cached) or Storage(uncached).
1316 @param FormSet FormSet data structure.
1317 @param Form Form data structure.
1318 @param Question Pointer to the Question.
1319 @param Cached TRUE: set to Edit copy FALSE: set to original
1322 @retval EFI_SUCCESS The function completed successfully.
1327 IN FORM_BROWSER_FORMSET
*FormSet
,
1328 IN FORM_BROWSER_FORM
*Form
,
1329 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1340 FORMSET_STORAGE
*Storage
;
1341 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1346 BOOLEAN IsBufferStorage
;
1353 Status
= EFI_SUCCESS
;
1356 // Statement don't have storage, skip them
1358 if (Question
->QuestionId
== 0) {
1363 // If Question value is provided by an Expression, then it is read only
1365 if (Question
->ValueExpression
!= NULL
) {
1370 // Question value is provided by RTC
1372 Storage
= Question
->Storage
;
1373 QuestionValue
= &Question
->HiiValue
.Value
;
1374 if (Storage
== NULL
) {
1376 // It's a Question without storage, or RTC date/time
1378 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1380 // Date and time define the same Flags bit
1382 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1383 case QF_DATE_STORAGE_TIME
:
1384 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1387 case QF_DATE_STORAGE_WAKEUP
:
1388 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1391 case QF_DATE_STORAGE_NORMAL
:
1394 // For date/time without storage
1399 if (EFI_ERROR (Status
)) {
1403 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1404 EfiTime
.Year
= QuestionValue
->date
.Year
;
1405 EfiTime
.Month
= QuestionValue
->date
.Month
;
1406 EfiTime
.Day
= QuestionValue
->date
.Day
;
1408 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1409 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1410 EfiTime
.Second
= QuestionValue
->time
.Second
;
1413 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1414 Status
= gRT
->SetTime (&EfiTime
);
1416 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1424 // Question value is provided by EFI variable
1426 StorageWidth
= Question
->StorageWidth
;
1427 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1428 if (Question
->BufferValue
!= NULL
) {
1429 Src
= Question
->BufferValue
;
1431 Src
= (UINT8
*) QuestionValue
;
1434 Status
= gRT
->SetVariable (
1435 Question
->VariableName
,
1437 Storage
->Attributes
,
1445 // Question Value is provided by Buffer Storage or NameValue Storage
1447 if (Question
->BufferValue
!= NULL
) {
1448 Src
= Question
->BufferValue
;
1450 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1453 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
1454 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1455 if (IsBufferStorage
) {
1457 // Copy to storage edit buffer
1459 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1463 // Allocate enough string buffer.
1466 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1467 Value
= AllocateZeroPool (BufferLen
);
1468 ASSERT (Value
!= NULL
);
1470 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1472 TemName
= (CHAR16
*) Src
;
1474 for (; *TemName
!= L
'\0'; TemName
++) {
1475 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1478 BufferLen
= StorageWidth
* 2 + 1;
1479 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1480 ASSERT (Value
!= NULL
);
1482 // Convert Buffer to Hex String
1484 TemBuffer
= Src
+ StorageWidth
- 1;
1486 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1487 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1491 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
);
1497 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1498 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1500 if (IsBufferStorage
) {
1501 Length
= StrLen (Question
->BlockName
) + 7;
1503 Length
= StrLen (Question
->VariableName
) + 2;
1505 if (!IsBufferStorage
&& IsString
) {
1506 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1508 Length
+= (StorageWidth
* 2);
1510 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1511 ASSERT (ConfigResp
!= NULL
);
1513 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1514 if (IsBufferStorage
) {
1515 StrCat (ConfigResp
, Question
->BlockName
);
1516 StrCat (ConfigResp
, L
"&VALUE=");
1518 StrCat (ConfigResp
, L
"&");
1519 StrCat (ConfigResp
, Question
->VariableName
);
1520 StrCat (ConfigResp
, L
"=");
1523 Value
= ConfigResp
+ StrLen (ConfigResp
);
1525 if (!IsBufferStorage
&& IsString
) {
1527 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1529 TemName
= (CHAR16
*) Src
;
1531 for (; *TemName
!= L
'\0'; TemName
++) {
1532 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1536 // Convert Buffer to Hex String
1538 TemBuffer
= Src
+ StorageWidth
- 1;
1540 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1541 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1546 // Convert to lower char.
1548 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1549 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1550 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1555 // Submit Question Value to Configuration Driver
1557 if (FormSet
->ConfigAccess
!= NULL
) {
1558 Status
= FormSet
->ConfigAccess
->RouteConfig (
1559 FormSet
->ConfigAccess
,
1563 if (EFI_ERROR (Status
)) {
1564 FreePool (ConfigResp
);
1568 FreePool (ConfigResp
);
1571 // Synchronize shadow Buffer
1573 SynchronizeStorage (Storage
);
1581 Perform inconsistent check for a Form.
1583 @param FormSet FormSet data structure.
1584 @param Form Form data structure.
1585 @param Question The Question to be validated.
1586 @param Type Validation type: InConsistent or NoSubmit
1588 @retval EFI_SUCCESS Form validation pass.
1589 @retval other Form validation failed.
1594 IN FORM_BROWSER_FORMSET
*FormSet
,
1595 IN FORM_BROWSER_FORM
*Form
,
1596 IN FORM_BROWSER_STATEMENT
*Question
,
1602 LIST_ENTRY
*ListHead
;
1605 FORM_EXPRESSION
*Expression
;
1607 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1608 ListHead
= &Question
->InconsistentListHead
;
1609 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1610 ListHead
= &Question
->NoSubmitListHead
;
1612 return EFI_UNSUPPORTED
;
1615 Link
= GetFirstNode (ListHead
);
1616 while (!IsNull (ListHead
, Link
)) {
1617 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1620 // Evaluate the expression
1622 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1623 if (EFI_ERROR (Status
)) {
1627 if (Expression
->Result
.Value
.b
) {
1629 // Condition meet, show up error message
1631 if (Expression
->Error
!= 0) {
1632 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1634 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1635 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1639 return EFI_NOT_READY
;
1642 Link
= GetNextNode (ListHead
, Link
);
1650 Perform NoSubmit check for a Form.
1652 @param FormSet FormSet data structure.
1653 @param Form Form data structure.
1655 @retval EFI_SUCCESS Form validation pass.
1656 @retval other Form validation failed.
1661 IN FORM_BROWSER_FORMSET
*FormSet
,
1662 IN FORM_BROWSER_FORM
*Form
1667 FORM_BROWSER_STATEMENT
*Question
;
1669 Link
= GetFirstNode (&Form
->StatementListHead
);
1670 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1671 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1673 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1674 if (EFI_ERROR (Status
)) {
1678 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1688 @param FormSet FormSet data structure.
1689 @param Form Form data structure.
1691 @retval EFI_SUCCESS The function completed successfully.
1696 IN FORM_BROWSER_FORMSET
*FormSet
,
1697 IN FORM_BROWSER_FORM
*Form
1702 EFI_STRING ConfigResp
;
1703 EFI_STRING Progress
;
1704 FORMSET_STORAGE
*Storage
;
1707 // Validate the Form by NoSubmit check
1709 Status
= NoSubmitCheck (FormSet
, Form
);
1710 if (EFI_ERROR (Status
)) {
1715 // Submit Buffer storage or Name/Value storage
1717 Link
= GetFirstNode (&FormSet
->StorageListHead
);
1718 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
1719 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
1720 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
1722 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1727 // Skip if there is no RequestElement
1729 if (Storage
->ElementCount
== 0) {
1734 // Prepare <ConfigResp>
1736 Status
= StorageToConfigResp (Storage
, &ConfigResp
);
1737 if (EFI_ERROR (Status
)) {
1742 // Send <ConfigResp> to Configuration Driver
1744 if (FormSet
->ConfigAccess
!= NULL
) {
1745 Status
= FormSet
->ConfigAccess
->RouteConfig (
1746 FormSet
->ConfigAccess
,
1750 if (EFI_ERROR (Status
)) {
1751 FreePool (ConfigResp
);
1755 FreePool (ConfigResp
);
1758 // Config success, update storage shadow Buffer
1760 SynchronizeStorage (Storage
);
1763 gNvUpdateRequired
= FALSE
;
1770 Reset Question to its default value.
1772 @param FormSet The form set.
1773 @param Form The form.
1774 @param Question The question.
1775 @param DefaultId The Class of the default.
1777 @retval EFI_SUCCESS Question is reset to default value.
1781 GetQuestionDefault (
1782 IN FORM_BROWSER_FORMSET
*FormSet
,
1783 IN FORM_BROWSER_FORM
*Form
,
1784 IN FORM_BROWSER_STATEMENT
*Question
,
1790 QUESTION_DEFAULT
*Default
;
1791 QUESTION_OPTION
*Option
;
1792 EFI_HII_VALUE
*HiiValue
;
1794 EFI_STRING StrValue
;
1796 Status
= EFI_SUCCESS
;
1800 // Statement don't have storage, skip them
1802 if (Question
->QuestionId
== 0) {
1807 // There are three ways to specify default value for a Question:
1808 // 1, use nested EFI_IFR_DEFAULT (highest priority)
1809 // 2, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
1810 // 3, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
1812 HiiValue
= &Question
->HiiValue
;
1815 // EFI_IFR_DEFAULT has highest priority
1817 if (!IsListEmpty (&Question
->DefaultListHead
)) {
1818 Link
= GetFirstNode (&Question
->DefaultListHead
);
1819 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
1820 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
1822 if (Default
->DefaultId
== DefaultId
) {
1823 if (Default
->ValueExpression
!= NULL
) {
1825 // Default is provided by an Expression, evaluate it
1827 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
1828 if (EFI_ERROR (Status
)) {
1832 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1835 // Default value is embedded in EFI_IFR_DEFAULT
1837 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
1840 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1841 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
1842 if (StrValue
== NULL
) {
1843 return EFI_NOT_FOUND
;
1845 Question
->BufferValue
= AllocateCopyPool (StrSize (StrValue
), StrValue
);
1851 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
1856 // EFI_ONE_OF_OPTION
1858 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
1859 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1861 // OneOfOption could only provide Standard and Manufacturing default
1863 Link
= GetFirstNode (&Question
->OptionListHead
);
1864 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1865 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1867 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
1868 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
1870 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1875 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1881 // EFI_IFR_CHECKBOX - lowest priority
1883 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
1884 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1886 // Checkbox could only provide Standard and Manufacturing default
1888 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
1889 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
1891 HiiValue
->Value
.b
= TRUE
;
1893 HiiValue
->Value
.b
= FALSE
;
1901 // For Questions without default
1903 switch (Question
->Operand
) {
1904 case EFI_IFR_ONE_OF_OP
:
1906 // Take first oneof option as oneof's default value
1908 if (ValueToOption (Question
, HiiValue
) == NULL
) {
1909 Link
= GetFirstNode (&Question
->OptionListHead
);
1910 if (!IsNull (&Question
->OptionListHead
, Link
)) {
1911 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1912 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
1917 case EFI_IFR_ORDERED_LIST_OP
:
1919 // Take option sequence in IFR as ordered list's default value
1922 Link
= GetFirstNode (&Question
->OptionListHead
);
1923 while (!IsNull (&Question
->OptionListHead
, Link
)) {
1924 Option
= QUESTION_OPTION_FROM_LINK (Link
);
1926 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
1929 if (Index
>= Question
->MaxContainers
) {
1933 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
1938 Status
= EFI_NOT_FOUND
;
1947 Reset Questions in a Form to their default value.
1949 @param FormSet FormSet data structure.
1950 @param Form The Form which to be reset.
1951 @param DefaultId The Class of the default.
1953 @retval EFI_SUCCESS The function completed successfully.
1957 ExtractFormDefault (
1958 IN FORM_BROWSER_FORMSET
*FormSet
,
1959 IN FORM_BROWSER_FORM
*Form
,
1965 FORM_BROWSER_STATEMENT
*Question
;
1967 Link
= GetFirstNode (&Form
->StatementListHead
);
1968 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1969 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1970 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1973 // If Question is disabled, don't reset it to default
1975 if (Question
->DisableExpression
!= NULL
) {
1976 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
1977 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
1983 // Reset Question to its default value
1985 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
1986 if (EFI_ERROR (Status
)) {
1991 // Synchronize Buffer storage's Edit buffer
1993 if ((Question
->Storage
!= NULL
) &&
1994 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
1995 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2004 Initialize Question's Edit copy from Storage.
2006 @param FormSet FormSet data structure.
2007 @param Form Form data structure.
2009 @retval EFI_SUCCESS The function completed successfully.
2014 IN FORM_BROWSER_FORMSET
*FormSet
,
2015 IN FORM_BROWSER_FORM
*Form
2020 FORM_BROWSER_STATEMENT
*Question
;
2022 Link
= GetFirstNode (&Form
->StatementListHead
);
2023 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2024 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2027 // Initialize local copy of Value for each Question
2029 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
2030 if (EFI_ERROR (Status
)) {
2034 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2042 Initialize Question's Edit copy from Storage for the whole Formset.
2044 @param FormSet FormSet data structure.
2046 @retval EFI_SUCCESS The function completed successfully.
2051 IN FORM_BROWSER_FORMSET
*FormSet
2056 FORM_BROWSER_FORM
*Form
;
2058 Link
= GetFirstNode (&FormSet
->FormListHead
);
2059 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2060 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2063 // Initialize local copy of Value for each Form
2065 Status
= LoadFormConfig (FormSet
, Form
);
2066 if (EFI_ERROR (Status
)) {
2070 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2078 Fill storage's edit copy with settings requested from Configuration Driver.
2080 @param FormSet FormSet data structure.
2081 @param Storage Buffer Storage.
2083 @retval EFI_SUCCESS The function completed successfully.
2088 IN FORM_BROWSER_FORMSET
*FormSet
,
2089 IN FORMSET_STORAGE
*Storage
2093 EFI_STRING Progress
;
2097 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2101 if (FormSet
->ConfigAccess
== NULL
) {
2102 return EFI_NOT_FOUND
;
2105 if (Storage
->ElementCount
== 0) {
2107 // Skip if there is no RequestElement
2113 // Request current settings from Configuration Driver
2115 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2116 FormSet
->ConfigAccess
,
2117 Storage
->ConfigRequest
,
2121 if (EFI_ERROR (Status
)) {
2126 // Convert Result from <ConfigAltResp> to <ConfigResp>
2128 StrPtr
= StrStr (Result
, L
"ALTCFG");
2129 if (StrPtr
!= NULL
) {
2133 Status
= ConfigRespToStorage (Storage
, Result
);
2140 Copy uncommitted data from source Storage to destination Storage.
2142 @param Dst Target Storage for uncommitted data.
2143 @param Src Source Storage for uncommitted data.
2145 @retval EFI_SUCCESS The function completed successfully.
2146 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
2151 IN OUT FORMSET_STORAGE
*Dst
,
2152 IN FORMSET_STORAGE
*Src
2156 NAME_VALUE_NODE
*Node
;
2158 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
2159 return EFI_INVALID_PARAMETER
;
2162 switch (Src
->Type
) {
2163 case EFI_HII_VARSTORE_BUFFER
:
2164 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
2167 case EFI_HII_VARSTORE_NAME_VALUE
:
2168 Link
= GetFirstNode (&Src
->NameValueListHead
);
2169 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
2170 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2172 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
);
2174 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
2178 case EFI_HII_VARSTORE_EFI_VARIABLE
:
2188 Get current setting of Questions.
2190 @param FormSet FormSet data structure.
2192 @retval EFI_SUCCESS The function completed successfully.
2196 InitializeCurrentSetting (
2197 IN OUT FORM_BROWSER_FORMSET
*FormSet
2202 FORMSET_STORAGE
*Storage
;
2203 FORMSET_STORAGE
*StorageSrc
;
2204 FORMSET_STORAGE
*OldStorage
;
2205 FORM_BROWSER_FORM
*Form
;
2209 // Extract default from IFR binary
2211 Link
= GetFirstNode (&FormSet
->FormListHead
);
2212 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
2213 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2215 Status
= ExtractFormDefault (FormSet
, Form
, EFI_HII_DEFAULT_CLASS_STANDARD
);
2217 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
2221 // Request current settings from Configuration Driver
2223 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2224 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2225 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2228 if (gOldFormSet
!= NULL
) {
2230 // Try to find the Storage in backup formset gOldFormSet
2232 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
2233 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
2234 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
2236 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
2237 OldStorage
= StorageSrc
;
2241 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
2245 if (OldStorage
== NULL
) {
2247 // Storage is not found in backup formset, request it from ConfigDriver
2249 Status
= LoadStorage (FormSet
, Storage
);
2252 // Storage found in backup formset, use it
2254 Status
= CopyStorage (Storage
, OldStorage
);
2258 // Now Edit Buffer is filled with default values(lower priority) and current
2259 // settings(higher priority), sychronize it to shadow Buffer
2261 if (!EFI_ERROR (Status
)) {
2262 SynchronizeStorage (Storage
);
2265 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2273 Fetch the Ifr binary data of a FormSet.
2275 @param Handle PackageList Handle
2276 @param FormSetGuid GUID of a formset. If not specified (NULL or zero
2277 GUID), take the first FormSet found in package
2279 @param BinaryLength The length of the FormSet IFR binary.
2280 @param BinaryData The buffer designed to receive the FormSet.
2282 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
2283 BufferLength was updated.
2284 @retval EFI_INVALID_PARAMETER The handle is unknown.
2285 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
2286 be found with the requested FormId.
2291 IN EFI_HII_HANDLE Handle
,
2292 IN OUT EFI_GUID
*FormSetGuid
,
2293 OUT UINTN
*BinaryLength
,
2294 OUT UINT8
**BinaryData
2298 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
2304 BOOLEAN ReturnDefault
;
2305 UINT32 PackageListLength
;
2306 EFI_HII_PACKAGE_HEADER PackageHeader
;
2308 UINT8 NumberOfClassGuid
;
2309 BOOLEAN IsSetupClassGuid
;
2310 EFI_GUID
*ClassGuid
;
2314 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));;
2317 // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list
2319 if (FormSetGuid
== NULL
|| CompareGuid (FormSetGuid
, &gZeroGuid
)) {
2320 ReturnDefault
= TRUE
;
2322 ReturnDefault
= FALSE
;
2326 // Get HII PackageList
2329 HiiPackageList
= NULL
;
2330 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2331 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2332 HiiPackageList
= AllocatePool (BufferSize
);
2333 ASSERT (HiiPackageList
!= NULL
);
2335 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
2337 if (EFI_ERROR (Status
)) {
2340 ASSERT (HiiPackageList
!= NULL
);
2343 // Get Form package from this HII package List
2345 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
2347 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
2349 while (Offset
< PackageListLength
) {
2350 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
2351 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
2353 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
2355 // Search FormSet in this Form Package
2357 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
2358 while (Offset2
< PackageHeader
.Length
) {
2359 OpCodeData
= Package
+ Offset2
;
2361 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
2363 // Check whether return default FormSet
2365 if (ReturnDefault
) {
2367 // Check ClassGuid of formset OpCode
2369 IsSetupClassGuid
= FALSE
;
2370 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
2371 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
2372 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
2373 if (CompareGuid (ClassGuid
+ Index
, &gEfiHiiPlatformSetupFormsetGuid
)) {
2374 IsSetupClassGuid
= TRUE
;
2378 if (IsSetupClassGuid
) {
2384 // FormSet GUID is specified, check it
2386 if (CompareGuid (FormSetGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
2391 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
2394 if (Offset2
< PackageHeader
.Length
) {
2396 // Target formset found
2402 Offset
+= PackageHeader
.Length
;
2405 if (Offset
>= PackageListLength
) {
2407 // Form package not found in this Package List
2409 FreePool (HiiPackageList
);
2410 return EFI_NOT_FOUND
;
2413 if (ReturnDefault
&& FormSetGuid
!= NULL
) {
2415 // Return the default FormSet GUID
2417 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
2421 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
2422 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
2423 // of the Form Package.
2425 *BinaryLength
= PackageHeader
.Length
- Offset2
;
2426 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
2428 FreePool (HiiPackageList
);
2430 if (*BinaryData
== NULL
) {
2431 return EFI_OUT_OF_RESOURCES
;
2439 Initialize the internal data structure of a FormSet.
2441 @param Handle PackageList Handle
2442 @param FormSetGuid GUID of a formset. If not specified (NULL or zero
2443 GUID), take the first FormSet found in package
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
);