2 Entry and initialization module for the browser.
4 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 SETUP_DRIVER_PRIVATE_DATA mPrivateData
= {
18 SETUP_DRIVER_SIGNATURE
,
32 EFI_HII_DATABASE_PROTOCOL
*mHiiDatabase
;
33 EFI_HII_STRING_PROTOCOL
*mHiiString
;
34 EFI_HII_CONFIG_ROUTING_PROTOCOL
*mHiiConfigRouting
;
36 UINTN gBrowserContextCount
= 0;
37 LIST_ENTRY gBrowserContextList
= INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList
);
38 LIST_ENTRY gBrowserFormSetList
= INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList
);
39 LIST_ENTRY gBrowserHotKeyList
= INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList
);
41 BANNER_DATA
*gBannerData
;
42 EFI_HII_HANDLE gFrontPageHandle
;
44 UINTN gFunctionKeySetting
;
45 BOOLEAN gResetRequired
;
46 EFI_HII_HANDLE gHiiHandle
;
48 EFI_SCREEN_DESCRIPTOR gScreenDimensions
;
49 BROWSER_SETTING_SCOPE gBrowserSettingScope
= FormSetLevel
;
50 BOOLEAN mBrowserScopeFirstSet
= TRUE
;
51 EXIT_HANDLER ExitHandlerFunction
= NULL
;
55 // Browser Global Strings
58 CHAR16
*gDiscardFailed
;
59 CHAR16
*gDefaultFailed
;
61 CHAR16
*gEnterCommitString
;
62 CHAR16
*gEnterEscapeString
;
63 CHAR16
*gEscapeString
;
64 CHAR16
*gMoveHighlight
;
65 CHAR16
*gMakeSelection
;
66 CHAR16
*gDecNumericInput
;
67 CHAR16
*gHexNumericInput
;
68 CHAR16
*gToggleCheckBox
;
69 CHAR16
*gPromptForData
;
70 CHAR16
*gPromptForPassword
;
71 CHAR16
*gPromptForNewPassword
;
72 CHAR16
*gConfirmPassword
;
73 CHAR16
*gConfirmError
;
74 CHAR16
*gPassowordInvalid
;
83 CHAR16
*gAdjustNumber
;
85 CHAR16
*gOptionMismatch
;
86 CHAR16
*gFormSuppress
;
88 CHAR16
*mUnknownString
= L
"!";
90 CHAR16 gPromptBlockWidth
;
91 CHAR16 gOptionBlockWidth
;
92 CHAR16 gHelpBlockWidth
;
94 EFI_GUID gZeroGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
95 EFI_GUID gSetupBrowserGuid
= {
96 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
99 FORM_BROWSER_FORMSET
*gOldFormSet
= NULL
;
101 FUNCTIION_KEY_SETTING gFunctionKeySettingTable
[] = {
121 NONE_FUNCTION_KEY_SETTING
142 NONE_FUNCTION_KEY_SETTING
163 NONE_FUNCTION_KEY_SETTING
166 // BMM File Explorer FormSet.
184 NONE_FUNCTION_KEY_SETTING
189 This is the routine which an external caller uses to direct the browser
190 where to obtain it's information.
193 @param This The Form Browser protocol instanse.
194 @param Handles A pointer to an array of Handles. If HandleCount > 1 we
195 display a list of the formsets for the handles specified.
196 @param HandleCount The number of Handles specified in Handle.
197 @param FormSetGuid This field points to the EFI_GUID which must match the Guid
198 field in the EFI_IFR_FORM_SET op-code for the specified
199 forms-based package. If FormSetGuid is NULL, then this
200 function will display the first found forms package.
201 @param FormId This field specifies which EFI_IFR_FORM to render as the first
202 displayable page. If this field has a value of 0x0000, then
203 the forms browser will render the specified forms in their encoded order.
204 @param ScreenDimensions Points to recommended form dimensions, including any non-content area, in
206 @param ActionRequest Points to the action recommended by the form.
208 @retval EFI_SUCCESS The function completed successfully.
209 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
210 @retval EFI_NOT_FOUND No valid forms could be found to display.
216 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
217 IN EFI_HII_HANDLE
*Handles
,
218 IN UINTN HandleCount
,
219 IN EFI_GUID
*FormSetGuid
, OPTIONAL
220 IN UINT16 FormId
, OPTIONAL
221 IN CONST EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
222 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest OPTIONAL
226 UI_MENU_SELECTION
*Selection
;
228 FORM_BROWSER_FORMSET
*FormSet
;
232 // Calculate total number of Register HotKeys.
235 Link
= GetFirstNode (&gBrowserHotKeyList
);
236 while (!IsNull (&gBrowserHotKeyList
, Link
)) {
237 Link
= GetNextNode (&gBrowserHotKeyList
, Link
);
241 // Show three HotKeys help information on one ROW.
243 gFooterHeight
= FOOTER_HEIGHT
+ (Index
/ 3);
246 // Save globals used by SendForm()
248 SaveBrowserContext ();
250 gResetRequired
= FALSE
;
251 Status
= EFI_SUCCESS
;
252 ZeroMem (&gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
255 // Seed the dimensions in the global
257 gST
->ConOut
->QueryMode (
259 gST
->ConOut
->Mode
->Mode
,
260 &gScreenDimensions
.RightColumn
,
261 &gScreenDimensions
.BottomRow
264 if (ScreenDimensions
!= NULL
) {
266 // Check local dimension vs. global dimension.
268 if ((gScreenDimensions
.RightColumn
< ScreenDimensions
->RightColumn
) ||
269 (gScreenDimensions
.BottomRow
< ScreenDimensions
->BottomRow
)
271 Status
= EFI_INVALID_PARAMETER
;
275 // Local dimension validation.
277 if ((ScreenDimensions
->RightColumn
> ScreenDimensions
->LeftColumn
) &&
278 (ScreenDimensions
->BottomRow
> ScreenDimensions
->TopRow
) &&
279 ((ScreenDimensions
->RightColumn
- ScreenDimensions
->LeftColumn
) > 2) &&
281 (ScreenDimensions
->BottomRow
- ScreenDimensions
->TopRow
) > STATUS_BAR_HEIGHT
+
282 SCROLL_ARROW_HEIGHT
*
284 FRONT_PAGE_HEADER_HEIGHT
+
289 CopyMem (&gScreenDimensions
, (VOID
*) ScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
291 Status
= EFI_INVALID_PARAMETER
;
297 gOptionBlockWidth
= (CHAR16
) ((gScreenDimensions
.RightColumn
- gScreenDimensions
.LeftColumn
) / 3);
298 gPromptBlockWidth
= (CHAR16
) (gOptionBlockWidth
+ LEFT_SKIPPED_COLUMNS
);
299 gHelpBlockWidth
= (CHAR16
) (gOptionBlockWidth
- LEFT_SKIPPED_COLUMNS
);
302 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
304 InitializeBrowserStrings ();
306 gFunctionKeySetting
= ENABLE_FUNCTION_KEY_SETTING
;
309 // Ensure we are in Text mode
311 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
313 for (Index
= 0; Index
< HandleCount
; Index
++) {
314 Selection
= AllocateZeroPool (sizeof (UI_MENU_SELECTION
));
315 ASSERT (Selection
!= NULL
);
317 Selection
->Handle
= Handles
[Index
];
318 if (FormSetGuid
!= NULL
) {
319 CopyMem (&Selection
->FormSetGuid
, FormSetGuid
, sizeof (EFI_GUID
));
320 Selection
->FormId
= FormId
;
322 CopyMem (&Selection
->FormSetGuid
, &gEfiHiiPlatformSetupFormsetGuid
, sizeof (EFI_GUID
));
326 // Try to find pre FormSet in the maintain backup list.
328 gOldFormSet
= GetFormSetFromHiiHandle (Selection
->Handle
);
331 FormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
332 ASSERT (FormSet
!= NULL
);
335 // Initialize internal data structures of FormSet
337 Status
= InitializeFormSet (Selection
->Handle
, &Selection
->FormSetGuid
, FormSet
);
338 if (EFI_ERROR (Status
) || IsListEmpty (&FormSet
->FormListHead
)) {
339 DestroyFormSet (FormSet
);
342 Selection
->FormSet
= FormSet
;
345 // Display this formset
347 gCurrentSelection
= Selection
;
349 Status
= SetupBrowser (Selection
);
351 gCurrentSelection
= NULL
;
353 if (EFI_ERROR (Status
)) {
357 } while (Selection
->Action
== UI_ACTION_REFRESH_FORMSET
);
359 if (gOldFormSet
!= NULL
) {
361 // If no data is changed, don't need to save current FormSet into the maintain list.
363 if (!IsNvUpdateRequired (gOldFormSet
)) {
364 RemoveEntryList (&gOldFormSet
->Link
);
365 DestroyFormSet (gOldFormSet
);
370 FreePool (Selection
);
373 if (ActionRequest
!= NULL
) {
374 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
375 if (gResetRequired
) {
376 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_RESET
;
380 FreeBrowserStrings ();
382 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
383 gST
->ConOut
->ClearScreen (gST
->ConOut
);
387 // Restore globals used by SendForm()
389 RestoreBrowserContext ();
396 This function is called by a callback handler to retrieve uncommitted state
397 data from the browser.
399 @param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
401 @param ResultsDataSize A pointer to the size of the buffer associated
403 @param ResultsData A string returned from an IFR browser or
404 equivalent. The results string will have no
405 routing information in them.
406 @param RetrieveData A BOOLEAN field which allows an agent to retrieve
407 (if RetrieveData = TRUE) data from the uncommitted
408 browser state information or set (if RetrieveData
409 = FALSE) data in the uncommitted browser state
411 @param VariableGuid An optional field to indicate the target variable
413 @param VariableName An optional field to indicate the target
414 human-readable variable name.
416 @retval EFI_SUCCESS The results have been distributed or are awaiting
418 @retval EFI_BUFFER_TOO_SMALL The ResultsDataSize specified was too small to
419 contain the results data.
425 IN CONST EFI_FORM_BROWSER2_PROTOCOL
*This
,
426 IN OUT UINTN
*ResultsDataSize
,
427 IN OUT EFI_STRING ResultsData
,
428 IN BOOLEAN RetrieveData
,
429 IN CONST EFI_GUID
*VariableGuid
, OPTIONAL
430 IN CONST CHAR16
*VariableName OPTIONAL
435 FORMSET_STORAGE
*Storage
;
436 FORM_BROWSER_FORMSET
*FormSet
;
443 if (ResultsDataSize
== NULL
|| ResultsData
== NULL
) {
444 return EFI_INVALID_PARAMETER
;
447 if (gCurrentSelection
== NULL
) {
448 return EFI_NOT_READY
;
453 FormSet
= gCurrentSelection
->FormSet
;
456 // Find target storage
458 Link
= GetFirstNode (&FormSet
->StorageListHead
);
459 if (IsNull (&FormSet
->StorageListHead
, Link
)) {
460 return EFI_UNSUPPORTED
;
463 if (VariableGuid
!= NULL
) {
465 // Try to find target storage
468 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
469 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
470 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
472 if (CompareGuid (&Storage
->Guid
, (EFI_GUID
*) VariableGuid
)) {
473 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
474 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
476 // Buffer storage require both GUID and Name
478 if (VariableName
== NULL
) {
479 return EFI_NOT_FOUND
;
482 if (StrCmp (Storage
->Name
, (CHAR16
*) VariableName
) != 0) {
492 return EFI_NOT_FOUND
;
496 // GUID/Name is not specified, take the first storage in FormSet
498 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
503 // Skip if there is no RequestElement
505 if (Storage
->ElementCount
== 0) {
510 // Generate <ConfigResp>
512 Status
= StorageToConfigResp (Storage
, &ConfigResp
, FALSE
);
513 if (EFI_ERROR (Status
)) {
518 // Skip <ConfigHdr> and '&' to point to <ConfigBody>
520 StrPtr
= ConfigResp
+ StrLen (Storage
->ConfigHdr
) + 1;
522 BufferSize
= StrSize (StrPtr
);
523 if (*ResultsDataSize
< BufferSize
) {
524 *ResultsDataSize
= BufferSize
;
526 FreePool (ConfigResp
);
527 return EFI_BUFFER_TOO_SMALL
;
530 *ResultsDataSize
= BufferSize
;
531 CopyMem (ResultsData
, StrPtr
, BufferSize
);
533 FreePool (ConfigResp
);
536 // Prepare <ConfigResp>
538 TmpSize
= StrLen (ResultsData
);
539 BufferSize
= (TmpSize
+ StrLen (Storage
->ConfigHdr
) + 2) * sizeof (CHAR16
);
540 ConfigResp
= AllocateZeroPool (BufferSize
);
541 ASSERT (ConfigResp
!= NULL
);
543 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
544 StrCat (ConfigResp
, L
"&");
545 StrCat (ConfigResp
, ResultsData
);
548 // Update Browser uncommited data
550 Status
= ConfigRespToStorage (Storage
, ConfigResp
);
551 if (EFI_ERROR (Status
)) {
560 Notify function will remove the formset in the maintain list
561 once this formset is removed.
563 Functions which are registered to receive notification of
564 database events have this prototype. The actual event is encoded
565 in NotifyType. The following table describes how PackageType,
566 PackageGuid, Handle, and Package are used for each of the
569 @param PackageType Package type of the notification.
571 @param PackageGuid If PackageType is
572 EFI_HII_PACKAGE_TYPE_GUID, then this is
573 the pointer to the GUID from the Guid
574 field of EFI_HII_PACKAGE_GUID_HEADER.
575 Otherwise, it must be NULL.
577 @param Package Points to the package referred to by the
578 notification Handle The handle of the package
579 list which contains the specified package.
581 @param Handle The HII handle.
583 @param NotifyType The type of change concerning the
585 EFI_HII_DATABASE_NOTIFY_TYPE.
590 FormsetRemoveNotify (
591 IN UINT8 PackageType
,
592 IN CONST EFI_GUID
*PackageGuid
,
593 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
594 IN EFI_HII_HANDLE Handle
,
595 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
598 FORM_BROWSER_FORMSET
*FormSet
;
601 // Ignore the update for current using formset, which is handled by another notify function.
603 if (IsHiiHandleInBrowserContext (Handle
)) {
608 // Remove the backup FormSet data when the Form Package is removed.
610 FormSet
= GetFormSetFromHiiHandle (Handle
);
611 if (FormSet
!= NULL
) {
612 RemoveEntryList (&FormSet
->Link
);
613 DestroyFormSet (FormSet
);
620 Initialize Setup Browser driver.
622 @param ImageHandle The image handle.
623 @param SystemTable The system table.
625 @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
626 @return Other value if failed to initialize the Setup Browser module.
632 IN EFI_HANDLE ImageHandle
,
633 IN EFI_SYSTEM_TABLE
*SystemTable
637 EFI_HANDLE NotifyHandle
;
638 EFI_INPUT_KEY DefaultHotKey
;
639 EFI_STRING HelpString
;
642 // Locate required Hii relative protocols
644 Status
= gBS
->LocateProtocol (
645 &gEfiHiiDatabaseProtocolGuid
,
647 (VOID
**) &mHiiDatabase
649 ASSERT_EFI_ERROR (Status
);
651 Status
= gBS
->LocateProtocol (
652 &gEfiHiiStringProtocolGuid
,
654 (VOID
**) &mHiiString
656 ASSERT_EFI_ERROR (Status
);
658 Status
= gBS
->LocateProtocol (
659 &gEfiHiiConfigRoutingProtocolGuid
,
661 (VOID
**) &mHiiConfigRouting
663 ASSERT_EFI_ERROR (Status
);
666 // Publish our HII data
668 gHiiHandle
= HiiAddPackages (
674 ASSERT (gHiiHandle
!= NULL
);
677 // Initialize Driver private data
679 gBannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
680 ASSERT (gBannerData
!= NULL
);
683 // Initialize generic help strings.
685 gSaveFailed
= GetToken (STRING_TOKEN (SAVE_FAILED
), gHiiHandle
);
686 gDiscardFailed
= GetToken (STRING_TOKEN (DISCARD_FAILED
), gHiiHandle
);
687 gDefaultFailed
= GetToken (STRING_TOKEN (DEFAULT_FAILED
), gHiiHandle
);
690 // Install FormBrowser2 protocol
692 mPrivateData
.Handle
= NULL
;
693 Status
= gBS
->InstallProtocolInterface (
694 &mPrivateData
.Handle
,
695 &gEfiFormBrowser2ProtocolGuid
,
696 EFI_NATIVE_INTERFACE
,
697 &mPrivateData
.FormBrowser2
699 ASSERT_EFI_ERROR (Status
);
702 // Install default HotKey F10 for Save
704 DefaultHotKey
.UnicodeChar
= CHAR_NULL
;
705 HelpString
= GetToken (STRING_TOKEN (FUNCTION_TEN_STRING
), gHiiHandle
);
706 DefaultHotKey
.ScanCode
= SCAN_F10
;
707 RegisterHotKey (&DefaultHotKey
, BROWSER_ACTION_SUBMIT
, 0, HelpString
);
708 FreePool (HelpString
);
710 // Install default HotKey F9 for Reset To Defaults
712 DefaultHotKey
.ScanCode
= SCAN_F9
;
713 HelpString
= GetToken (STRING_TOKEN (FUNCTION_NINE_STRING
), gHiiHandle
);
714 RegisterHotKey (&DefaultHotKey
, BROWSER_ACTION_DEFAULT
, EFI_HII_DEFAULT_CLASS_STANDARD
, HelpString
);
715 FreePool (HelpString
);
718 // Install FormBrowserEx protocol
720 mPrivateData
.Handle
= NULL
;
721 Status
= gBS
->InstallProtocolInterface (
722 &mPrivateData
.Handle
,
723 &gEfiFormBrowserExProtocolGuid
,
724 EFI_NATIVE_INTERFACE
,
725 &mPrivateData
.FormBrowserEx
727 ASSERT_EFI_ERROR (Status
);
730 // Register notify for Form package remove
732 Status
= mHiiDatabase
->RegisterPackageNotify (
734 EFI_HII_PACKAGE_FORMS
,
737 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
740 ASSERT_EFI_ERROR (Status
);
747 Create a new string in HII Package List.
749 @param String The String to be added
750 @param HiiHandle The package list in the HII database to insert the
753 @return The output string.
759 IN EFI_HII_HANDLE HiiHandle
762 EFI_STRING_ID StringId
;
764 StringId
= HiiSetString (HiiHandle
, 0, String
, NULL
);
765 ASSERT (StringId
!= 0);
772 Delete a string from HII Package List.
774 @param StringId Id of the string in HII database.
775 @param HiiHandle The HII package list handle.
777 @retval EFI_SUCCESS The string was deleted successfully.
782 IN EFI_STRING_ID StringId
,
783 IN EFI_HII_HANDLE HiiHandle
788 NullChar
= CHAR_NULL
;
789 HiiSetString (HiiHandle
, StringId
, &NullChar
, NULL
);
795 Get the string based on the StringId and HII Package List Handle.
797 @param Token The String's ID.
798 @param HiiHandle The package list in the HII database to search for
799 the specified string.
801 @return The output string.
806 IN EFI_STRING_ID Token
,
807 IN EFI_HII_HANDLE HiiHandle
812 if (HiiHandle
== NULL
) {
816 String
= HiiGetString (HiiHandle
, Token
, NULL
);
817 if (String
== NULL
) {
818 String
= AllocateCopyPool (sizeof (mUnknownString
), mUnknownString
);
819 ASSERT (String
!= NULL
);
821 return (CHAR16
*) String
;
826 Allocate new memory and then copy the Unicode string Source to Destination.
828 @param Dest Location to copy string
829 @param Src String to copy
834 IN OUT CHAR16
**Dest
,
841 *Dest
= AllocateCopyPool (StrSize (Src
), Src
);
842 ASSERT (*Dest
!= NULL
);
847 Allocate new memory and concatinate Source on the end of Destination.
849 @param Dest String to added to the end of.
850 @param Src String to concatinate.
855 IN OUT CHAR16
**Dest
,
863 NewStringCpy (Dest
, Src
);
867 TmpSize
= StrSize (*Dest
);
868 NewString
= AllocateZeroPool (TmpSize
+ StrSize (Src
) - 1);
869 ASSERT (NewString
!= NULL
);
871 StrCpy (NewString
, *Dest
);
872 StrCat (NewString
, Src
);
880 Synchronize or restore Storage's Edit copy and Shadow copy.
882 @param Storage The Storage to be synchronized.
883 @param SyncOrRestore Sync the buffer to editbuffer or Restore the
885 if TRUE, copy the editbuffer to the buffer.
886 if FALSE, copy the buffer to the editbuffer.
891 IN FORMSET_STORAGE
*Storage
,
892 IN BOOLEAN SyncOrRestore
896 NAME_VALUE_NODE
*Node
;
898 switch (Storage
->Type
) {
899 case EFI_HII_VARSTORE_BUFFER
:
900 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
902 CopyMem (Storage
->Buffer
, Storage
->EditBuffer
, Storage
->Size
);
904 CopyMem (Storage
->EditBuffer
, Storage
->Buffer
, Storage
->Size
);
908 case EFI_HII_VARSTORE_NAME_VALUE
:
909 Link
= GetFirstNode (&Storage
->NameValueListHead
);
910 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
911 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
914 NewStringCpy (&Node
->Value
, Node
->EditValue
);
916 NewStringCpy (&Node
->EditValue
, Node
->Value
);
919 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
923 case EFI_HII_VARSTORE_EFI_VARIABLE
:
931 Get Value for given Name from a NameValue Storage.
933 @param Storage The NameValue Storage.
934 @param Name The Name.
935 @param Value The retured Value.
937 @retval EFI_SUCCESS Value found for given Name.
938 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
943 IN FORMSET_STORAGE
*Storage
,
945 IN OUT CHAR16
**Value
949 NAME_VALUE_NODE
*Node
;
953 Link
= GetFirstNode (&Storage
->NameValueListHead
);
954 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
955 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
957 if (StrCmp (Name
, Node
->Name
) == 0) {
958 NewStringCpy (Value
, Node
->EditValue
);
962 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
965 return EFI_NOT_FOUND
;
970 Set Value of given Name in a NameValue Storage.
972 @param Storage The NameValue Storage.
973 @param Name The Name.
974 @param Value The Value to set.
975 @param Edit Whether update editValue or Value.
977 @retval EFI_SUCCESS Value found for given Name.
978 @retval EFI_NOT_FOUND No such Name found in NameValue storage.
983 IN FORMSET_STORAGE
*Storage
,
990 NAME_VALUE_NODE
*Node
;
993 Link
= GetFirstNode (&Storage
->NameValueListHead
);
994 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
995 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
997 if (StrCmp (Name
, Node
->Name
) == 0) {
999 Buffer
= Node
->EditValue
;
1001 Buffer
= Node
->Value
;
1003 if (Buffer
!= NULL
) {
1006 Buffer
= AllocateCopyPool (StrSize (Value
), Value
);
1007 ASSERT (Buffer
!= NULL
);
1009 Node
->EditValue
= Buffer
;
1011 Node
->Value
= Buffer
;
1016 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
1019 return EFI_NOT_FOUND
;
1024 Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.
1026 @param Buffer The Storage to be conveted.
1027 @param ConfigResp The returned <ConfigResp>.
1028 @param SingleForm Whether update data for single form or formset level.
1030 @retval EFI_SUCCESS Convert success.
1031 @retval EFI_INVALID_PARAMETER Incorrect storage type.
1035 StorageToConfigResp (
1037 IN CHAR16
**ConfigResp
,
1038 IN BOOLEAN SingleForm
1042 EFI_STRING Progress
;
1044 NAME_VALUE_NODE
*Node
;
1045 CHAR16
*ConfigRequest
;
1046 FORMSET_STORAGE
*Storage
;
1047 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
1049 Status
= EFI_SUCCESS
;
1051 ConfigInfo
= (FORM_BROWSER_CONFIG_REQUEST
*) Buffer
;
1052 Storage
= ConfigInfo
->Storage
;
1053 ConfigRequest
= ConfigInfo
->ConfigRequest
;
1055 Storage
= (FORMSET_STORAGE
*) Buffer
;
1056 ConfigRequest
= Storage
->ConfigRequest
;
1059 switch (Storage
->Type
) {
1060 case EFI_HII_VARSTORE_BUFFER
:
1061 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
1062 Status
= mHiiConfigRouting
->BlockToConfig (
1065 Storage
->EditBuffer
,
1072 case EFI_HII_VARSTORE_NAME_VALUE
:
1074 NewStringCat (ConfigResp
, Storage
->ConfigHdr
);
1076 Link
= GetFirstNode (&Storage
->NameValueListHead
);
1077 while (!IsNull (&Storage
->NameValueListHead
, Link
)) {
1078 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
1080 if (StrStr (ConfigRequest
, Node
->Name
) != NULL
) {
1081 NewStringCat (ConfigResp
, L
"&");
1082 NewStringCat (ConfigResp
, Node
->Name
);
1083 NewStringCat (ConfigResp
, L
"=");
1084 NewStringCat (ConfigResp
, Node
->EditValue
);
1086 Link
= GetNextNode (&Storage
->NameValueListHead
, Link
);
1090 case EFI_HII_VARSTORE_EFI_VARIABLE
:
1092 Status
= EFI_INVALID_PARAMETER
;
1101 Convert <ConfigResp> to settings in Buffer Storage or NameValue Storage.
1103 @param Storage The Storage to receive the settings.
1104 @param ConfigResp The <ConfigResp> to be converted.
1106 @retval EFI_SUCCESS Convert success.
1107 @retval EFI_INVALID_PARAMETER Incorrect storage type.
1111 ConfigRespToStorage (
1112 IN FORMSET_STORAGE
*Storage
,
1113 IN CHAR16
*ConfigResp
1117 EFI_STRING Progress
;
1123 Status
= EFI_SUCCESS
;
1125 switch (Storage
->Type
) {
1126 case EFI_HII_VARSTORE_BUFFER
:
1127 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
1128 BufferSize
= Storage
->Size
;
1129 Status
= mHiiConfigRouting
->ConfigToBlock (
1132 Storage
->EditBuffer
,
1138 case EFI_HII_VARSTORE_NAME_VALUE
:
1139 StrPtr
= StrStr (ConfigResp
, L
"PATH");
1140 if (StrPtr
== NULL
) {
1143 StrPtr
= StrStr (ConfigResp
, L
"&");
1144 while (StrPtr
!= NULL
) {
1148 StrPtr
= StrPtr
+ 1;
1150 StrPtr
= StrStr (StrPtr
, L
"=");
1151 if (StrPtr
== NULL
) {
1159 StrPtr
= StrPtr
+ 1;
1161 StrPtr
= StrStr (StrPtr
, L
"&");
1162 if (StrPtr
!= NULL
) {
1165 SetValueByName (Storage
, Name
, Value
, TRUE
);
1169 case EFI_HII_VARSTORE_EFI_VARIABLE
:
1171 Status
= EFI_INVALID_PARAMETER
;
1180 Get Question's current Value.
1182 @param FormSet FormSet data structure.
1183 @param Form Form data structure.
1184 @param Question Question to be initialized.
1185 @param Cached TRUE: get from Edit copy FALSE: get from original
1188 @retval EFI_SUCCESS The function completed successfully.
1193 IN FORM_BROWSER_FORMSET
*FormSet
,
1194 IN FORM_BROWSER_FORM
*Form
,
1195 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1205 FORMSET_STORAGE
*Storage
;
1206 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1207 CHAR16
*ConfigRequest
;
1215 BOOLEAN IsBufferStorage
;
1221 Status
= EFI_SUCCESS
;
1225 // Statement don't have storage, skip them
1227 if (Question
->QuestionId
== 0) {
1232 // Question value is provided by an Expression, evaluate it
1234 if (Question
->ValueExpression
!= NULL
) {
1235 Status
= EvaluateExpression (FormSet
, Form
, Question
->ValueExpression
);
1236 if (!EFI_ERROR (Status
)) {
1237 CopyMem (&Question
->HiiValue
, &Question
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
1243 // Get question value by read expression.
1245 if (Question
->ReadExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1246 Status
= EvaluateExpression (FormSet
, Form
, Question
->ReadExpression
);
1247 if (!EFI_ERROR (Status
) && (Question
->ReadExpression
->Result
.Type
< EFI_IFR_TYPE_OTHER
)) {
1249 // Only update question value to the valid result.
1251 CopyMem (&Question
->HiiValue
, &Question
->ReadExpression
->Result
, sizeof (EFI_HII_VALUE
));
1257 // Question value is provided by RTC
1259 Storage
= Question
->Storage
;
1260 QuestionValue
= &Question
->HiiValue
.Value
;
1261 if (Storage
== NULL
) {
1263 // It's a Question without storage, or RTC date/time
1265 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1267 // Date and time define the same Flags bit
1269 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1270 case QF_DATE_STORAGE_TIME
:
1271 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1274 case QF_DATE_STORAGE_WAKEUP
:
1275 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1278 case QF_DATE_STORAGE_NORMAL
:
1281 // For date/time without storage
1286 if (EFI_ERROR (Status
)) {
1290 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1291 QuestionValue
->date
.Year
= EfiTime
.Year
;
1292 QuestionValue
->date
.Month
= EfiTime
.Month
;
1293 QuestionValue
->date
.Day
= EfiTime
.Day
;
1295 QuestionValue
->time
.Hour
= EfiTime
.Hour
;
1296 QuestionValue
->time
.Minute
= EfiTime
.Minute
;
1297 QuestionValue
->time
.Second
= EfiTime
.Second
;
1305 // Question value is provided by EFI variable
1307 StorageWidth
= Question
->StorageWidth
;
1308 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1309 if (Question
->BufferValue
!= NULL
) {
1310 Dst
= Question
->BufferValue
;
1312 Dst
= (UINT8
*) QuestionValue
;
1315 Status
= gRT
->GetVariable (
1316 Question
->VariableName
,
1323 // Always return success, even this EFI variable doesn't exist
1329 // Question Value is provided by Buffer Storage or NameValue Storage
1331 if (Question
->BufferValue
!= NULL
) {
1333 // This Question is password or orderedlist
1335 Dst
= Question
->BufferValue
;
1338 // Other type of Questions
1340 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
1343 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
1344 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1345 IsBufferStorage
= TRUE
;
1347 IsBufferStorage
= FALSE
;
1349 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1351 if (IsBufferStorage
) {
1353 // Copy from storage Edit buffer
1355 CopyMem (Dst
, Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1358 Status
= GetValueByName (Storage
, Question
->VariableName
, &Value
);
1359 if (EFI_ERROR (Status
)) {
1363 ASSERT (Value
!= NULL
);
1364 LengthStr
= StrLen (Value
);
1365 Status
= EFI_SUCCESS
;
1368 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1369 // Add string tail char L'\0' into Length
1371 Length
= StorageWidth
+ sizeof (CHAR16
);
1372 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1373 Status
= EFI_BUFFER_TOO_SMALL
;
1375 StringPtr
= (CHAR16
*) Dst
;
1376 ZeroMem (TemStr
, sizeof (TemStr
));
1377 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1378 StrnCpy (TemStr
, Value
+ Index
, 4);
1379 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1382 // Add tailing L'\0' character
1384 StringPtr
[Index
/4] = L
'\0';
1387 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1388 Status
= EFI_BUFFER_TOO_SMALL
;
1390 ZeroMem (TemStr
, sizeof (TemStr
));
1391 for (Index
= 0; Index
< LengthStr
; Index
++) {
1392 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1393 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1394 if ((Index
& 1) == 0) {
1395 Dst
[Index
/2] = DigitUint8
;
1397 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1406 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
1408 // Request current settings from Configuration Driver
1410 if (FormSet
->ConfigAccess
== NULL
) {
1411 return EFI_NOT_FOUND
;
1415 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
1416 // <ConfigHdr> + "&" + <VariableName>
1418 if (IsBufferStorage
) {
1419 Length
= StrLen (Storage
->ConfigHdr
);
1420 Length
+= StrLen (Question
->BlockName
);
1422 Length
= StrLen (Storage
->ConfigHdr
);
1423 Length
+= StrLen (Question
->VariableName
) + 1;
1425 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
1426 ASSERT (ConfigRequest
!= NULL
);
1428 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
1429 if (IsBufferStorage
) {
1430 StrCat (ConfigRequest
, Question
->BlockName
);
1432 StrCat (ConfigRequest
, L
"&");
1433 StrCat (ConfigRequest
, Question
->VariableName
);
1436 Status
= FormSet
->ConfigAccess
->ExtractConfig (
1437 FormSet
->ConfigAccess
,
1442 FreePool (ConfigRequest
);
1443 if (EFI_ERROR (Status
)) {
1448 // Skip <ConfigRequest>
1450 if (IsBufferStorage
) {
1451 Value
= StrStr (Result
, L
"&VALUE");
1452 if (Value
== NULL
) {
1454 return EFI_NOT_FOUND
;
1461 Value
= Result
+ Length
;
1463 if (*Value
!= '=') {
1465 return EFI_NOT_FOUND
;
1468 // Skip '=', point to value
1473 // Suppress <AltResp> if any
1476 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
1481 LengthStr
= StrLen (Value
);
1482 Status
= EFI_SUCCESS
;
1483 if (!IsBufferStorage
&& IsString
) {
1485 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1486 // Add string tail char L'\0' into Length
1488 Length
= StorageWidth
+ sizeof (CHAR16
);
1489 if (Length
< ((LengthStr
/ 4 + 1) * 2)) {
1490 Status
= EFI_BUFFER_TOO_SMALL
;
1492 StringPtr
= (CHAR16
*) Dst
;
1493 ZeroMem (TemStr
, sizeof (TemStr
));
1494 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
1495 StrnCpy (TemStr
, Value
+ Index
, 4);
1496 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
1499 // Add tailing L'\0' character
1501 StringPtr
[Index
/4] = L
'\0';
1504 if (StorageWidth
< ((LengthStr
+ 1) / 2)) {
1505 Status
= EFI_BUFFER_TOO_SMALL
;
1507 ZeroMem (TemStr
, sizeof (TemStr
));
1508 for (Index
= 0; Index
< LengthStr
; Index
++) {
1509 TemStr
[0] = Value
[LengthStr
- Index
- 1];
1510 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
1511 if ((Index
& 1) == 0) {
1512 Dst
[Index
/2] = DigitUint8
;
1514 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
1521 if (EFI_ERROR (Status
)) {
1524 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1526 TemBuffer
= AllocateZeroPool (Storage
->Size
);
1527 if (TemBuffer
== NULL
) {
1528 Status
= EFI_OUT_OF_RESOURCES
;
1531 Length
= Storage
->Size
;
1532 Status
= gRT
->GetVariable (
1539 if (EFI_ERROR (Status
)) {
1540 FreePool (TemBuffer
);
1544 CopyMem (Dst
, TemBuffer
+ Question
->VarStoreInfo
.VarOffset
, StorageWidth
);
1546 FreePool (TemBuffer
);
1550 // Synchronize Edit Buffer
1552 if (IsBufferStorage
) {
1553 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Dst
, StorageWidth
);
1555 SetValueByName (Storage
, Question
->VariableName
, Value
, TRUE
);
1564 Save Question Value to edit copy(cached) or Storage(uncached).
1566 @param FormSet FormSet data structure.
1567 @param Form Form data structure.
1568 @param Question Pointer to the Question.
1569 @param Cached TRUE: set to Edit copy FALSE: set to original
1572 @retval EFI_SUCCESS The function completed successfully.
1577 IN FORM_BROWSER_FORMSET
*FormSet
,
1578 IN FORM_BROWSER_FORM
*Form
,
1579 IN OUT FORM_BROWSER_STATEMENT
*Question
,
1590 FORMSET_STORAGE
*Storage
;
1591 EFI_IFR_TYPE_VALUE
*QuestionValue
;
1596 BOOLEAN IsBufferStorage
;
1603 Status
= EFI_SUCCESS
;
1606 // Statement don't have storage, skip them
1608 if (Question
->QuestionId
== 0) {
1613 // If Question value is provided by an Expression, then it is read only
1615 if (Question
->ValueExpression
!= NULL
) {
1620 // Before set question value, evaluate its write expression.
1622 if (Question
->WriteExpression
!= NULL
&& Form
->FormType
== STANDARD_MAP_FORM_TYPE
) {
1623 Status
= EvaluateExpression (FormSet
, Form
, Question
->WriteExpression
);
1624 if (EFI_ERROR (Status
)) {
1630 // Question value is provided by RTC
1632 Storage
= Question
->Storage
;
1633 QuestionValue
= &Question
->HiiValue
.Value
;
1634 if (Storage
== NULL
) {
1636 // It's a Question without storage, or RTC date/time
1638 if (Question
->Operand
== EFI_IFR_DATE_OP
|| Question
->Operand
== EFI_IFR_TIME_OP
) {
1640 // Date and time define the same Flags bit
1642 switch (Question
->Flags
& EFI_QF_DATE_STORAGE
) {
1643 case QF_DATE_STORAGE_TIME
:
1644 Status
= gRT
->GetTime (&EfiTime
, NULL
);
1647 case QF_DATE_STORAGE_WAKEUP
:
1648 Status
= gRT
->GetWakeupTime (&Enabled
, &Pending
, &EfiTime
);
1651 case QF_DATE_STORAGE_NORMAL
:
1654 // For date/time without storage
1659 if (EFI_ERROR (Status
)) {
1663 if (Question
->Operand
== EFI_IFR_DATE_OP
) {
1664 EfiTime
.Year
= QuestionValue
->date
.Year
;
1665 EfiTime
.Month
= QuestionValue
->date
.Month
;
1666 EfiTime
.Day
= QuestionValue
->date
.Day
;
1668 EfiTime
.Hour
= QuestionValue
->time
.Hour
;
1669 EfiTime
.Minute
= QuestionValue
->time
.Minute
;
1670 EfiTime
.Second
= QuestionValue
->time
.Second
;
1673 if ((Question
->Flags
& EFI_QF_DATE_STORAGE
) == QF_DATE_STORAGE_TIME
) {
1674 Status
= gRT
->SetTime (&EfiTime
);
1676 Status
= gRT
->SetWakeupTime (TRUE
, &EfiTime
);
1684 // Question value is provided by EFI variable
1686 StorageWidth
= Question
->StorageWidth
;
1687 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
1688 if (Question
->BufferValue
!= NULL
) {
1689 Src
= Question
->BufferValue
;
1691 Src
= (UINT8
*) QuestionValue
;
1694 Status
= gRT
->SetVariable (
1695 Question
->VariableName
,
1697 Storage
->Attributes
,
1705 // Question Value is provided by Buffer Storage or NameValue Storage
1707 if (Question
->BufferValue
!= NULL
) {
1708 Src
= Question
->BufferValue
;
1710 Src
= (UINT8
*) &Question
->HiiValue
.Value
;
1713 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
1714 Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1715 IsBufferStorage
= TRUE
;
1717 IsBufferStorage
= FALSE
;
1719 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
1720 if (IsBufferStorage
) {
1722 // Copy to storage edit buffer
1724 CopyMem (Storage
->EditBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1728 // Allocate enough string buffer.
1731 BufferLen
= ((StrLen ((CHAR16
*) Src
) * 4) + 1) * sizeof (CHAR16
);
1732 Value
= AllocateZeroPool (BufferLen
);
1733 ASSERT (Value
!= NULL
);
1735 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1737 TemName
= (CHAR16
*) Src
;
1739 for (; *TemName
!= L
'\0'; TemName
++) {
1740 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1743 BufferLen
= StorageWidth
* 2 + 1;
1744 Value
= AllocateZeroPool (BufferLen
* sizeof (CHAR16
));
1745 ASSERT (Value
!= NULL
);
1747 // Convert Buffer to Hex String
1749 TemBuffer
= Src
+ StorageWidth
- 1;
1751 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1752 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1756 Status
= SetValueByName (Storage
, Question
->VariableName
, Value
, TRUE
);
1761 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
1763 // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
1764 // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
1766 if (IsBufferStorage
) {
1767 Length
= StrLen (Question
->BlockName
) + 7;
1769 Length
= StrLen (Question
->VariableName
) + 2;
1771 if (!IsBufferStorage
&& IsString
) {
1772 Length
+= (StrLen ((CHAR16
*) Src
) * 4);
1774 Length
+= (StorageWidth
* 2);
1776 ConfigResp
= AllocateZeroPool ((StrLen (Storage
->ConfigHdr
) + Length
+ 1) * sizeof (CHAR16
));
1777 ASSERT (ConfigResp
!= NULL
);
1779 StrCpy (ConfigResp
, Storage
->ConfigHdr
);
1780 if (IsBufferStorage
) {
1781 StrCat (ConfigResp
, Question
->BlockName
);
1782 StrCat (ConfigResp
, L
"&VALUE=");
1784 StrCat (ConfigResp
, L
"&");
1785 StrCat (ConfigResp
, Question
->VariableName
);
1786 StrCat (ConfigResp
, L
"=");
1789 Value
= ConfigResp
+ StrLen (ConfigResp
);
1791 if (!IsBufferStorage
&& IsString
) {
1793 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
1795 TemName
= (CHAR16
*) Src
;
1797 for (; *TemName
!= L
'\0'; TemName
++) {
1798 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemName
, 4);
1802 // Convert Buffer to Hex String
1804 TemBuffer
= Src
+ StorageWidth
- 1;
1806 for (Index
= 0; Index
< StorageWidth
; Index
++, TemBuffer
--) {
1807 TemString
+= UnicodeValueToString (TemString
, PREFIX_ZERO
| RADIX_HEX
, *TemBuffer
, 2);
1812 // Convert to lower char.
1814 for (TemString
= Value
; *Value
!= L
'\0'; Value
++) {
1815 if (*Value
>= L
'A' && *Value
<= L
'Z') {
1816 *Value
= (CHAR16
) (*Value
- L
'A' + L
'a');
1821 // Submit Question Value to Configuration Driver
1823 if (FormSet
->ConfigAccess
!= NULL
) {
1824 Status
= FormSet
->ConfigAccess
->RouteConfig (
1825 FormSet
->ConfigAccess
,
1829 if (EFI_ERROR (Status
)) {
1830 FreePool (ConfigResp
);
1834 FreePool (ConfigResp
);
1836 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
1838 TemBuffer
= AllocateZeroPool(Storage
->Size
);
1839 if (TemBuffer
== NULL
) {
1840 Status
= EFI_OUT_OF_RESOURCES
;
1843 Length
= Storage
->Size
;
1844 Status
= gRT
->GetVariable (
1852 CopyMem (TemBuffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1854 Status
= gRT
->SetVariable (
1857 Storage
->Attributes
,
1861 FreePool (TemBuffer
);
1862 if (EFI_ERROR (Status
)){
1867 // Sync storage, from editbuffer to buffer.
1869 CopyMem (Storage
->Buffer
+ Question
->VarStoreInfo
.VarOffset
, Src
, StorageWidth
);
1877 Perform inconsistent check for a Form.
1879 @param FormSet FormSet data structure.
1880 @param Form Form data structure.
1881 @param Question The Question to be validated.
1882 @param Type Validation type: InConsistent or NoSubmit
1884 @retval EFI_SUCCESS Form validation pass.
1885 @retval other Form validation failed.
1890 IN FORM_BROWSER_FORMSET
*FormSet
,
1891 IN FORM_BROWSER_FORM
*Form
,
1892 IN FORM_BROWSER_STATEMENT
*Question
,
1898 LIST_ENTRY
*ListHead
;
1901 FORM_EXPRESSION
*Expression
;
1903 if (Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
) {
1904 ListHead
= &Question
->InconsistentListHead
;
1905 } else if (Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
1906 ListHead
= &Question
->NoSubmitListHead
;
1908 return EFI_UNSUPPORTED
;
1911 Link
= GetFirstNode (ListHead
);
1912 while (!IsNull (ListHead
, Link
)) {
1913 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
1916 // Evaluate the expression
1918 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
1919 if (EFI_ERROR (Status
)) {
1923 if (Expression
->Result
.Value
.b
) {
1925 // Condition meet, show up error message
1927 if (Expression
->Error
!= 0) {
1928 PopUp
= GetToken (Expression
->Error
, FormSet
->HiiHandle
);
1930 CreateDialog (4, TRUE
, 0, NULL
, &Key
, gEmptyString
, PopUp
, gPressEnter
, gEmptyString
);
1931 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1935 return EFI_NOT_READY
;
1938 Link
= GetNextNode (ListHead
, Link
);
1946 Perform NoSubmit check for each Form in FormSet.
1948 @param FormSet FormSet data structure.
1949 @param CurrentForm Current input form data structure.
1951 @retval EFI_SUCCESS Form validation pass.
1952 @retval other Form validation failed.
1957 IN FORM_BROWSER_FORMSET
*FormSet
,
1958 IN FORM_BROWSER_FORM
*CurrentForm
1963 FORM_BROWSER_STATEMENT
*Question
;
1964 FORM_BROWSER_FORM
*Form
;
1965 LIST_ENTRY
*LinkForm
;
1967 LinkForm
= GetFirstNode (&FormSet
->FormListHead
);
1968 while (!IsNull (&FormSet
->FormListHead
, LinkForm
)) {
1969 Form
= FORM_BROWSER_FORM_FROM_LINK (LinkForm
);
1970 LinkForm
= GetNextNode (&FormSet
->FormListHead
, LinkForm
);
1972 if (CurrentForm
!= NULL
&& CurrentForm
!= Form
) {
1976 Link
= GetFirstNode (&Form
->StatementListHead
);
1977 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1978 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1980 Status
= ValidateQuestion (FormSet
, Form
, Question
, EFI_HII_EXPRESSION_NO_SUBMIT_IF
);
1981 if (EFI_ERROR (Status
)) {
1985 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1993 Fill storage's edit copy with settings requested from Configuration Driver.
1995 @param FormSet FormSet data structure.
1996 @param ConfigInfo The config info related to this form.
1997 @param SyncOrRestore Sync the buffer to editbuffer or Restore the
1998 editbuffer to buffer
1999 if TRUE, copy the editbuffer to the buffer.
2000 if FALSE, copy the buffer to the editbuffer.
2002 @retval EFI_SUCCESS The function completed successfully.
2006 SynchronizeStorageForForm (
2007 IN FORM_BROWSER_FORMSET
*FormSet
,
2008 IN FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
,
2009 IN BOOLEAN SyncOrRestore
2013 EFI_STRING Progress
;
2017 NAME_VALUE_NODE
*Node
;
2021 Status
= EFI_SUCCESS
;
2023 if (FormSet
->ConfigAccess
== NULL
&& ConfigInfo
->Storage
->Type
!= EFI_HII_VARSTORE_NAME_VALUE
) {
2024 return EFI_NOT_FOUND
;
2027 if (ConfigInfo
->ElementCount
== 0) {
2029 // Skip if there is no RequestElement
2034 if (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
2035 (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
)) {
2036 BufferSize
= ConfigInfo
->Storage
->Size
;
2038 if (SyncOrRestore
) {
2039 Src
= ConfigInfo
->Storage
->EditBuffer
;
2040 Dst
= ConfigInfo
->Storage
->Buffer
;
2042 Src
= ConfigInfo
->Storage
->Buffer
;
2043 Dst
= ConfigInfo
->Storage
->EditBuffer
;
2046 Status
= mHiiConfigRouting
->BlockToConfig(
2048 ConfigInfo
->ConfigRequest
,
2054 if (EFI_ERROR (Status
)) {
2058 Status
= mHiiConfigRouting
->ConfigToBlock (
2065 if (Result
!= NULL
) {
2068 } else if (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
2069 Link
= GetFirstNode (&ConfigInfo
->Storage
->NameValueListHead
);
2070 while (!IsNull (&ConfigInfo
->Storage
->NameValueListHead
, Link
)) {
2071 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
2073 if (StrStr (ConfigInfo
->ConfigRequest
, Node
->Name
) != NULL
) {
2074 if (SyncOrRestore
) {
2075 NewStringCpy (&Node
->Value
, Node
->EditValue
);
2077 NewStringCpy (&Node
->EditValue
, Node
->Value
);
2081 Link
= GetNextNode (&ConfigInfo
->Storage
->NameValueListHead
, Link
);
2090 Discard data based on the input setting scope (Form, FormSet or System).
2092 @param FormSet FormSet data structure.
2093 @param Form Form data structure.
2094 @param SettingScope Setting Scope for Discard action.
2096 @retval EFI_SUCCESS The function completed successfully.
2097 @retval EFI_UNSUPPORTED Unsupport SettingScope.
2102 IN FORM_BROWSER_FORMSET
*FormSet
,
2103 IN FORM_BROWSER_FORM
*Form
,
2104 IN BROWSER_SETTING_SCOPE SettingScope
2108 FORMSET_STORAGE
*Storage
;
2109 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
2110 FORM_BROWSER_FORMSET
*LocalFormSet
;
2113 // Check the supported setting level.
2115 if (SettingScope
>= MaxLevel
) {
2116 return EFI_UNSUPPORTED
;
2119 if (SettingScope
== FormLevel
&& Form
->NvUpdateRequired
) {
2121 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
2122 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
2123 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
2124 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
2126 if (ConfigInfo
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2131 // Skip if there is no RequestElement
2133 if (ConfigInfo
->ElementCount
== 0) {
2138 // Prepare <ConfigResp>
2140 SynchronizeStorageForForm(FormSet
, ConfigInfo
, FALSE
);
2143 Form
->NvUpdateRequired
= FALSE
;
2144 } else if (SettingScope
== FormSetLevel
&& IsNvUpdateRequired(FormSet
)) {
2146 // Discard Buffer storage or Name/Value storage
2148 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2149 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2150 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2151 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2153 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2158 // Skip if there is no RequestElement
2160 if (Storage
->ElementCount
== 0) {
2164 SynchronizeStorage(Storage
, FALSE
);
2167 UpdateNvInfoInForm (FormSet
, FALSE
);
2168 } else if (SettingScope
== SystemLevel
) {
2170 // System Level Discard.
2174 // Discard changed value for each FormSet in the maintain list.
2176 Link
= GetFirstNode (&gBrowserFormSetList
);
2177 while (!IsNull (&gBrowserFormSetList
, Link
)) {
2178 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
2179 DiscardForm (LocalFormSet
, NULL
, FormSetLevel
);
2180 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
2181 if (!IsHiiHandleInBrowserContext (LocalFormSet
->HiiHandle
)) {
2183 // Remove maintain backup list after discard except for the current using FormSet.
2185 RemoveEntryList (&LocalFormSet
->Link
);
2186 DestroyFormSet (LocalFormSet
);
2195 Submit data based on the input Setting level (Form, FormSet or System).
2197 @param FormSet FormSet data structure.
2198 @param Form Form data structure.
2199 @param SettingScope Setting Scope for Submit action.
2201 @retval EFI_SUCCESS The function completed successfully.
2202 @retval EFI_UNSUPPORTED Unsupport SettingScope.
2207 IN FORM_BROWSER_FORMSET
*FormSet
,
2208 IN FORM_BROWSER_FORM
*Form
,
2209 IN BROWSER_SETTING_SCOPE SettingScope
2214 EFI_STRING ConfigResp
;
2215 EFI_STRING Progress
;
2216 FORMSET_STORAGE
*Storage
;
2219 FORM_BROWSER_FORMSET
*LocalFormSet
;
2220 FORM_BROWSER_CONFIG_REQUEST
*ConfigInfo
;
2223 // Check the supported setting level.
2225 if (SettingScope
>= MaxLevel
) {
2226 return EFI_UNSUPPORTED
;
2230 // Validate the Form by NoSubmit check
2232 Status
= EFI_SUCCESS
;
2233 if (SettingScope
== FormLevel
) {
2234 Status
= NoSubmitCheck (FormSet
, Form
);
2235 } else if (SettingScope
== FormSetLevel
) {
2236 Status
= NoSubmitCheck (FormSet
, NULL
);
2238 if (EFI_ERROR (Status
)) {
2242 if (SettingScope
== FormLevel
&& Form
->NvUpdateRequired
) {
2244 Link
= GetFirstNode (&Form
->ConfigRequestHead
);
2245 while (!IsNull (&Form
->ConfigRequestHead
, Link
)) {
2246 ConfigInfo
= FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link
);
2247 Link
= GetNextNode (&Form
->ConfigRequestHead
, Link
);
2249 Storage
= ConfigInfo
->Storage
;
2250 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2255 // Skip if there is no RequestElement
2257 if (ConfigInfo
->ElementCount
== 0) {
2262 // 1. Prepare <ConfigResp>
2264 Status
= StorageToConfigResp (ConfigInfo
, &ConfigResp
, TRUE
);
2265 if (EFI_ERROR (Status
)) {
2270 // 2. Set value to hii driver or efi variable.
2272 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
2273 Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
2275 // Send <ConfigResp> to Configuration Driver
2277 if (FormSet
->ConfigAccess
!= NULL
) {
2278 Status
= FormSet
->ConfigAccess
->RouteConfig (
2279 FormSet
->ConfigAccess
,
2283 if (EFI_ERROR (Status
)) {
2284 FreePool (ConfigResp
);
2288 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
2290 TmpBuf
= AllocateZeroPool(Storage
->Size
);
2291 if (TmpBuf
== NULL
) {
2292 Status
= EFI_OUT_OF_RESOURCES
;
2296 BufferSize
= Storage
->Size
;
2297 Status
= gRT
->GetVariable (
2304 if (EFI_ERROR (Status
)) {
2306 FreePool (ConfigResp
);
2309 ASSERT (BufferSize
== Storage
->Size
);
2310 Status
= mHiiConfigRouting
->ConfigToBlock (
2317 if (EFI_ERROR (Status
)) {
2319 FreePool (ConfigResp
);
2323 Status
= gRT
->SetVariable (
2326 Storage
->Attributes
,
2331 if (EFI_ERROR (Status
)) {
2332 FreePool (ConfigResp
);
2336 FreePool (ConfigResp
);
2338 // 3. Config success, update storage shadow Buffer, only update the data belong to this form.
2340 SynchronizeStorageForForm(FormSet
, ConfigInfo
, TRUE
);
2344 // 4. Update the NV flag.
2346 Form
->NvUpdateRequired
= FALSE
;
2347 } else if (SettingScope
== FormSetLevel
&& IsNvUpdateRequired(FormSet
)) {
2349 // Submit Buffer storage or Name/Value storage
2351 Link
= GetFirstNode (&FormSet
->StorageListHead
);
2352 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
2353 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
2354 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
2356 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
2361 // Skip if there is no RequestElement
2363 if (Storage
->ElementCount
== 0) {
2368 // 1. Prepare <ConfigResp>
2370 Status
= StorageToConfigResp (Storage
, &ConfigResp
, FALSE
);
2371 if (EFI_ERROR (Status
)) {
2375 if (Storage
->Type
== EFI_HII_VARSTORE_BUFFER
||
2376 Storage
->Type
== EFI_HII_VARSTORE_NAME_VALUE
) {
2379 // 2. Send <ConfigResp> to Configuration Driver
2381 if (FormSet
->ConfigAccess
!= NULL
) {
2382 Status
= FormSet
->ConfigAccess
->RouteConfig (
2383 FormSet
->ConfigAccess
,
2387 if (EFI_ERROR (Status
)) {
2388 FreePool (ConfigResp
);
2392 } else if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
2394 // 1&2. Set the edit data to the variable.
2397 TmpBuf
= AllocateZeroPool (Storage
->Size
);
2398 if (TmpBuf
== NULL
) {
2399 Status
= EFI_OUT_OF_RESOURCES
;
2402 BufferSize
= Storage
->Size
;
2403 Status
= gRT
->GetVariable (
2410 ASSERT (BufferSize
== Storage
->Size
);
2411 Status
= mHiiConfigRouting
->ConfigToBlock (
2418 if (EFI_ERROR (Status
)) {
2420 FreePool (ConfigResp
);
2424 Status
= gRT
->SetVariable (
2427 Storage
->Attributes
,
2431 if (EFI_ERROR (Status
)) {
2433 FreePool (ConfigResp
);
2438 FreePool (ConfigResp
);
2440 // 3. Config success, update storage shadow Buffer
2442 SynchronizeStorage (Storage
, TRUE
);
2446 // 4. Update the NV flag.
2448 UpdateNvInfoInForm (FormSet
, FALSE
);
2449 } else if (SettingScope
== SystemLevel
) {
2451 // System Level Save.
2455 // Save changed value for each FormSet in the maintain list.
2457 Link
= GetFirstNode (&gBrowserFormSetList
);
2458 while (!IsNull (&gBrowserFormSetList
, Link
)) {
2459 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
2460 SubmitForm (LocalFormSet
, NULL
, FormSetLevel
);
2461 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
2462 if (!IsHiiHandleInBrowserContext (LocalFormSet
->HiiHandle
)) {
2464 // Remove maintain backup list after save except for the current using FormSet.
2466 RemoveEntryList (&LocalFormSet
->Link
);
2467 DestroyFormSet (LocalFormSet
);
2476 Get Question default value from AltCfg string.
2478 @param FormSet The form set.
2479 @param Question The question.
2480 @param DefaultId The default Id.
2482 @retval EFI_SUCCESS Question is reset to default value.
2486 GetDefaultValueFromAltCfg (
2487 IN FORM_BROWSER_FORMSET
*FormSet
,
2488 IN OUT FORM_BROWSER_STATEMENT
*Question
,
2492 BOOLEAN IsBufferStorage
;
2495 FORMSET_STORAGE
*Storage
;
2496 CHAR16
*ConfigRequest
;
2509 Status
= EFI_NOT_FOUND
;
2512 ConfigRequest
= NULL
;
2516 Storage
= Question
->Storage
;
2518 if ((Storage
== NULL
) ||
2519 (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) ||
2520 (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
)) {
2525 // Question Value is provided by Buffer Storage or NameValue Storage
2527 if (Question
->BufferValue
!= NULL
) {
2529 // This Question is password or orderedlist
2531 Dst
= Question
->BufferValue
;
2534 // Other type of Questions
2536 Dst
= (UINT8
*) &Question
->HiiValue
.Value
;
2539 IsBufferStorage
= (BOOLEAN
) ((Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) ? TRUE
: FALSE
);
2540 IsString
= (BOOLEAN
) ((Question
->HiiValue
.Type
== EFI_IFR_TYPE_STRING
) ? TRUE
: FALSE
);
2543 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
2544 // <ConfigHdr> + "&" + <VariableName>
2546 if (IsBufferStorage
) {
2547 Length
= StrLen (Storage
->ConfigHdr
);
2548 Length
+= StrLen (Question
->BlockName
);
2550 Length
= StrLen (Storage
->ConfigHdr
);
2551 Length
+= StrLen (Question
->VariableName
) + 1;
2553 ConfigRequest
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
2554 ASSERT (ConfigRequest
!= NULL
);
2556 StrCpy (ConfigRequest
, Storage
->ConfigHdr
);
2557 if (IsBufferStorage
) {
2558 StrCat (ConfigRequest
, Question
->BlockName
);
2560 StrCat (ConfigRequest
, L
"&");
2561 StrCat (ConfigRequest
, Question
->VariableName
);
2564 Status
= FormSet
->ConfigAccess
->ExtractConfig (
2565 FormSet
->ConfigAccess
,
2570 if (EFI_ERROR (Status
)) {
2575 // Call ConfigRouting GetAltCfg(ConfigRoute, <ConfigResponse>, Guid, Name, DevicePath, AltCfgId, AltCfgResp)
2576 // Get the default configuration string according to the default ID.
2578 Status
= mHiiConfigRouting
->GetAltConfig (
2584 &DefaultId
, // it can be NULL to get the current setting.
2589 // The required setting can't be found. So, it is not required to be validated and set.
2591 if (EFI_ERROR (Status
)) {
2596 // Skip <ConfigRequest>
2598 if (IsBufferStorage
) {
2599 Value
= StrStr (ConfigResp
, L
"&VALUE");
2600 ASSERT (Value
!= NULL
);
2606 Value
= StrStr (ConfigResp
, Question
->VariableName
);
2607 ASSERT (Value
!= NULL
);
2609 Value
= Value
+ StrLen (Question
->VariableName
);
2611 if (*Value
!= '=') {
2612 Status
= EFI_NOT_FOUND
;
2616 // Skip '=', point to value
2621 // Suppress <AltResp> if any
2624 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
2629 LengthStr
= StrLen (Value
);
2630 if (!IsBufferStorage
&& IsString
) {
2631 StringPtr
= (CHAR16
*) Dst
;
2632 ZeroMem (TemStr
, sizeof (TemStr
));
2633 for (Index
= 0; Index
< LengthStr
; Index
+= 4) {
2634 StrnCpy (TemStr
, Value
+ Index
, 4);
2635 StringPtr
[Index
/4] = (CHAR16
) StrHexToUint64 (TemStr
);
2638 // Add tailing L'\0' character
2640 StringPtr
[Index
/4] = L
'\0';
2642 ZeroMem (TemStr
, sizeof (TemStr
));
2643 for (Index
= 0; Index
< LengthStr
; Index
++) {
2644 TemStr
[0] = Value
[LengthStr
- Index
- 1];
2645 DigitUint8
= (UINT8
) StrHexToUint64 (TemStr
);
2646 if ((Index
& 1) == 0) {
2647 Dst
[Index
/2] = DigitUint8
;
2649 Dst
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Dst
[Index
/2]);
2655 if (ConfigRequest
!= NULL
){
2656 FreePool (ConfigRequest
);
2659 if (ConfigResp
!= NULL
) {
2660 FreePool (ConfigResp
);
2663 if (Result
!= NULL
) {
2671 Get default Id value used for browser.
2673 @param DefaultId The default id value used by hii.
2675 @retval Browser used default value.
2679 GetDefaultIdForCallBack (
2683 if (DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) {
2684 return EFI_BROWSER_ACTION_DEFAULT_STANDARD
;
2685 } else if (DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2686 return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING
;
2687 } else if (DefaultId
== EFI_HII_DEFAULT_CLASS_SAFE
) {
2688 return EFI_BROWSER_ACTION_DEFAULT_SAFE
;
2689 } else if (DefaultId
>= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN
&& DefaultId
< EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN
+ 0x1000) {
2690 return EFI_BROWSER_ACTION_DEFAULT_PLATFORM
+ DefaultId
- EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN
;
2691 } else if (DefaultId
>= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN
&& DefaultId
< EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN
+ 0x1000) {
2692 return EFI_BROWSER_ACTION_DEFAULT_HARDWARE
+ DefaultId
- EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN
;
2693 } else if (DefaultId
>= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN
&& DefaultId
< EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN
+ 0x1000) {
2694 return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE
+ DefaultId
- EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN
;
2701 Reset Question to its default value.
2703 @param FormSet The form set.
2704 @param Form The form.
2705 @param Question The question.
2706 @param DefaultId The Class of the default.
2708 @retval EFI_SUCCESS Question is reset to default value.
2712 GetQuestionDefault (
2713 IN FORM_BROWSER_FORMSET
*FormSet
,
2714 IN FORM_BROWSER_FORM
*Form
,
2715 IN FORM_BROWSER_STATEMENT
*Question
,
2721 QUESTION_DEFAULT
*Default
;
2722 QUESTION_OPTION
*Option
;
2723 EFI_HII_VALUE
*HiiValue
;
2725 EFI_STRING StrValue
;
2726 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2727 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2730 Status
= EFI_NOT_FOUND
;
2734 // Statement don't have storage, skip them
2736 if (Question
->QuestionId
== 0) {
2741 // There are Five ways to specify default value for a Question:
2742 // 1, use call back function (highest priority)
2743 // 2, use ExtractConfig function
2744 // 3, use nested EFI_IFR_DEFAULT
2745 // 4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)
2746 // 5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)
2748 HiiValue
= &Question
->HiiValue
;
2751 // Get Question defaut value from call back function.
2753 ConfigAccess
= FormSet
->ConfigAccess
;
2754 Action
= GetDefaultIdForCallBack (DefaultId
);
2755 if ((Action
> 0) && ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) && (ConfigAccess
!= NULL
)) {
2756 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2757 Status
= ConfigAccess
->Callback (
2760 Question
->QuestionId
,
2765 if (!EFI_ERROR (Status
)) {
2771 // Get default value from altcfg string.
2773 if (ConfigAccess
!= NULL
) {
2774 Status
= GetDefaultValueFromAltCfg(FormSet
, Question
, DefaultId
);
2775 if (!EFI_ERROR (Status
)) {
2781 // EFI_IFR_DEFAULT has highest priority
2783 if (!IsListEmpty (&Question
->DefaultListHead
)) {
2784 Link
= GetFirstNode (&Question
->DefaultListHead
);
2785 while (!IsNull (&Question
->DefaultListHead
, Link
)) {
2786 Default
= QUESTION_DEFAULT_FROM_LINK (Link
);
2788 if (Default
->DefaultId
== DefaultId
) {
2789 if (Default
->ValueExpression
!= NULL
) {
2791 // Default is provided by an Expression, evaluate it
2793 Status
= EvaluateExpression (FormSet
, Form
, Default
->ValueExpression
);
2794 if (EFI_ERROR (Status
)) {
2798 CopyMem (HiiValue
, &Default
->ValueExpression
->Result
, sizeof (EFI_HII_VALUE
));
2801 // Default value is embedded in EFI_IFR_DEFAULT
2803 CopyMem (HiiValue
, &Default
->Value
, sizeof (EFI_HII_VALUE
));
2806 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2807 StrValue
= HiiGetString (FormSet
->HiiHandle
, HiiValue
->Value
.string
, NULL
);
2808 if (StrValue
== NULL
) {
2809 return EFI_NOT_FOUND
;
2811 if (Question
->StorageWidth
> StrSize (StrValue
)) {
2812 CopyMem (Question
->BufferValue
, StrValue
, StrSize (StrValue
));
2814 CopyMem (Question
->BufferValue
, StrValue
, Question
->StorageWidth
);
2821 Link
= GetNextNode (&Question
->DefaultListHead
, Link
);
2826 // EFI_ONE_OF_OPTION
2828 if ((Question
->Operand
== EFI_IFR_ONE_OF_OP
) && !IsListEmpty (&Question
->OptionListHead
)) {
2829 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2831 // OneOfOption could only provide Standard and Manufacturing default
2833 Link
= GetFirstNode (&Question
->OptionListHead
);
2834 while (!IsNull (&Question
->OptionListHead
, Link
)) {
2835 Option
= QUESTION_OPTION_FROM_LINK (Link
);
2837 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0)) ||
2838 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Option
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0))
2840 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
2845 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
2851 // EFI_IFR_CHECKBOX - lowest priority
2853 if (Question
->Operand
== EFI_IFR_CHECKBOX_OP
) {
2854 if (DefaultId
<= EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2856 // Checkbox could only provide Standard and Manufacturing default
2858 if (((DefaultId
== EFI_HII_DEFAULT_CLASS_STANDARD
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0)) ||
2859 ((DefaultId
== EFI_HII_DEFAULT_CLASS_MANUFACTURING
) && ((Question
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0))
2861 HiiValue
->Value
.b
= TRUE
;
2863 HiiValue
->Value
.b
= FALSE
;
2871 // For Questions without default
2873 Status
= EFI_NOT_FOUND
;
2874 switch (Question
->Operand
) {
2875 case EFI_IFR_NUMERIC_OP
:
2877 // Take minimum value as numeric default value
2879 if ((HiiValue
->Value
.u64
< Question
->Minimum
) || (HiiValue
->Value
.u64
> Question
->Maximum
)) {
2880 HiiValue
->Value
.u64
= Question
->Minimum
;
2881 Status
= EFI_SUCCESS
;
2885 case EFI_IFR_ONE_OF_OP
:
2887 // Take first oneof option as oneof's default value
2889 if (ValueToOption (Question
, HiiValue
) == NULL
) {
2890 Link
= GetFirstNode (&Question
->OptionListHead
);
2891 if (!IsNull (&Question
->OptionListHead
, Link
)) {
2892 Option
= QUESTION_OPTION_FROM_LINK (Link
);
2893 CopyMem (HiiValue
, &Option
->Value
, sizeof (EFI_HII_VALUE
));
2894 Status
= EFI_SUCCESS
;
2899 case EFI_IFR_ORDERED_LIST_OP
:
2901 // Take option sequence in IFR as ordered list's default value
2904 Link
= GetFirstNode (&Question
->OptionListHead
);
2905 while (!IsNull (&Question
->OptionListHead
, Link
)) {
2906 Status
= EFI_SUCCESS
;
2907 Option
= QUESTION_OPTION_FROM_LINK (Link
);
2909 SetArrayData (Question
->BufferValue
, Question
->ValueType
, Index
, Option
->Value
.Value
.u64
);
2912 if (Index
>= Question
->MaxContainers
) {
2916 Link
= GetNextNode (&Question
->OptionListHead
, Link
);
2929 Reset Questions to their default value in a Form, Formset or System.
2931 @param FormSet FormSet data structure.
2932 @param Form Form data structure.
2933 @param DefaultId The Class of the default.
2934 @param SettingScope Setting Scope for Default action.
2936 @retval EFI_SUCCESS The function completed successfully.
2937 @retval EFI_UNSUPPORTED Unsupport SettingScope.
2942 IN FORM_BROWSER_FORMSET
*FormSet
,
2943 IN FORM_BROWSER_FORM
*Form
,
2944 IN UINT16 DefaultId
,
2945 IN BROWSER_SETTING_SCOPE SettingScope
2949 LIST_ENTRY
*FormLink
;
2951 FORM_BROWSER_STATEMENT
*Question
;
2952 FORM_BROWSER_FORMSET
*BackUpFormSet
;
2953 FORM_BROWSER_FORMSET
*LocalFormSet
;
2954 EFI_HII_HANDLE
*HiiHandles
;
2957 UINTN BackUpClassOfVfr
;
2960 // Check the supported setting level.
2962 if (SettingScope
>= MaxLevel
) {
2963 return EFI_UNSUPPORTED
;
2966 if (SettingScope
== FormLevel
) {
2968 // Extract Form default
2970 Link
= GetFirstNode (&Form
->StatementListHead
);
2971 while (!IsNull (&Form
->StatementListHead
, Link
)) {
2972 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
2973 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
2976 // If Question is disabled, don't reset it to default
2978 if (Question
->DisableExpression
!= NULL
) {
2979 Status
= EvaluateExpression (FormSet
, Form
, Question
->DisableExpression
);
2980 if (!EFI_ERROR (Status
) && Question
->DisableExpression
->Result
.Value
.b
) {
2986 // Reset Question to its default value
2988 Status
= GetQuestionDefault (FormSet
, Form
, Question
, DefaultId
);
2989 if (EFI_ERROR (Status
)) {
2994 // Synchronize Buffer storage's Edit buffer
2996 if ((Question
->Storage
!= NULL
) &&
2997 (Question
->Storage
->Type
!= EFI_HII_VARSTORE_EFI_VARIABLE
)) {
2998 SetQuestionValue (FormSet
, Form
, Question
, TRUE
);
3000 // Update Form NV flag.
3002 Form
->NvUpdateRequired
= TRUE
;
3005 } else if (SettingScope
== FormSetLevel
) {
3006 FormLink
= GetFirstNode (&FormSet
->FormListHead
);
3007 while (!IsNull (&FormSet
->FormListHead
, FormLink
)) {
3008 Form
= FORM_BROWSER_FORM_FROM_LINK (FormLink
);
3009 ExtractDefault (FormSet
, Form
, DefaultId
, FormLevel
);
3010 FormLink
= GetNextNode (&FormSet
->FormListHead
, FormLink
);
3012 } else if (SettingScope
== SystemLevel
) {
3014 // Open all FormSet by locate HII packages.
3015 // Initiliaze the maintain FormSet to store default data as back up data.
3017 BackUpClassOfVfr
= gClassOfVfr
;
3018 BackUpFormSet
= gOldFormSet
;
3022 // Get all the Hii handles
3024 HiiHandles
= HiiGetHiiHandles (NULL
);
3025 ASSERT (HiiHandles
!= NULL
);
3028 // Search for formset of each class type
3030 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
3032 // Check HiiHandles[Index] does exist in global maintain list.
3034 if (GetFormSetFromHiiHandle (HiiHandles
[Index
]) != NULL
) {
3039 // Initilize FormSet Setting
3041 LocalFormSet
= AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET
));
3042 ASSERT (LocalFormSet
!= NULL
);
3043 ZeroMem (&ZeroGuid
, sizeof (ZeroGuid
));
3044 Status
= InitializeFormSet (HiiHandles
[Index
], &ZeroGuid
, LocalFormSet
);
3045 if (EFI_ERROR (Status
) || IsListEmpty (&LocalFormSet
->FormListHead
)) {
3046 DestroyFormSet (LocalFormSet
);
3049 Status
= InitializeCurrentSetting (LocalFormSet
);
3050 if (EFI_ERROR (Status
)) {
3051 DestroyFormSet (LocalFormSet
);
3056 // Add FormSet into the maintain list.
3058 InsertTailList (&gBrowserFormSetList
, &LocalFormSet
->Link
);
3062 // Free resources, and restore gOldFormSet and gClassOfVfr
3064 FreePool (HiiHandles
);
3065 gOldFormSet
= BackUpFormSet
;
3066 gClassOfVfr
= BackUpClassOfVfr
;
3069 // Set Default Value for each FormSet in the maintain list.
3071 Link
= GetFirstNode (&gBrowserFormSetList
);
3072 while (!IsNull (&gBrowserFormSetList
, Link
)) {
3073 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
3074 ExtractDefault (LocalFormSet
, NULL
, DefaultId
, FormSetLevel
);
3075 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
3083 Initialize Question's Edit copy from Storage.
3085 @param Selection Selection contains the information about
3086 the Selection, form and formset to be displayed.
3087 Selection action may be updated in retrieve callback.
3088 @param FormSet FormSet data structure.
3089 @param Form Form data structure.
3091 @retval EFI_SUCCESS The function completed successfully.
3096 IN OUT UI_MENU_SELECTION
*Selection
,
3097 IN FORM_BROWSER_FORMSET
*FormSet
,
3098 IN FORM_BROWSER_FORM
*Form
3103 FORM_BROWSER_STATEMENT
*Question
;
3107 Link
= GetFirstNode (&Form
->StatementListHead
);
3108 while (!IsNull (&Form
->StatementListHead
, Link
)) {
3109 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
3112 // Initialize local copy of Value for each Question
3114 Status
= GetQuestionValue (FormSet
, Form
, Question
, TRUE
);
3115 if (EFI_ERROR (Status
)) {
3119 if ((Question
->Operand
== EFI_IFR_STRING_OP
) || (Question
->Operand
== EFI_IFR_PASSWORD_OP
)) {
3120 HiiSetString (FormSet
->HiiHandle
, Question
->HiiValue
.Value
.string
, (CHAR16
*)Question
->BufferValue
, NULL
);
3124 // According the spec, ref opcode try to get value from call back with "retrieve" type.
3126 if ((Question
->Operand
== EFI_IFR_REF_OP
) && (FormSet
->ConfigAccess
!= NULL
)) {
3127 Status
= ProcessCallBackFunction(Selection
, Question
, EFI_BROWSER_ACTION_RETRIEVE
, TRUE
);
3128 if (EFI_ERROR (Status
)) {
3134 // Check whether EfiVarstore with CallBack can be got.
3136 if ((FormSet
->ConfigAccess
!= NULL
) &&
3137 (Selection
->Action
!= UI_ACTION_REFRESH_FORMSET
) &&
3138 (Question
->QuestionId
!= 0) &&
3139 (Question
->Storage
!= NULL
) &&
3140 (Question
->Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) &&
3141 ((Question
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
)) {
3144 // Check QuestionValue does exist.
3146 StorageWidth
= Question
->StorageWidth
;
3147 if (Question
->BufferValue
!= NULL
) {
3148 BufferValue
= Question
->BufferValue
;
3150 BufferValue
= (UINT8
*) &Question
->HiiValue
.Value
;
3152 Status
= gRT
->GetVariable (
3153 Question
->VariableName
,
3154 &Question
->Storage
->Guid
,
3160 if (!EFI_ERROR (Status
)) {
3161 Status
= ProcessCallBackFunction(Selection
, Question
, EFI_BROWSER_ACTION_RETRIEVE
, TRUE
);
3165 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
3172 Initialize Question's Edit copy from Storage for the whole Formset.
3174 @param Selection Selection contains the information about
3175 the Selection, form and formset to be displayed.
3176 Selection action may be updated in retrieve callback.
3177 @param FormSet FormSet data structure.
3179 @retval EFI_SUCCESS The function completed successfully.
3184 IN OUT UI_MENU_SELECTION
*Selection
,
3185 IN FORM_BROWSER_FORMSET
*FormSet
3190 FORM_BROWSER_FORM
*Form
;
3192 Link
= GetFirstNode (&FormSet
->FormListHead
);
3193 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
3194 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
3197 // Initialize local copy of Value for each Form
3199 Status
= LoadFormConfig (Selection
, FormSet
, Form
);
3200 if (EFI_ERROR (Status
)) {
3204 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
3211 Fill storage's edit copy with settings requested from Configuration Driver.
3213 @param FormSet FormSet data structure.
3214 @param Storage Buffer Storage.
3216 @retval EFI_SUCCESS The function completed successfully.
3221 IN FORM_BROWSER_FORMSET
*FormSet
,
3222 IN FORMSET_STORAGE
*Storage
3226 EFI_STRING Progress
;
3230 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE
) {
3234 if (Storage
->Type
== EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
) {
3235 Status
= gRT
->GetVariable (
3239 (UINTN
*)&Storage
->Size
,
3245 if (FormSet
->ConfigAccess
== NULL
) {
3246 return EFI_NOT_FOUND
;
3249 if (Storage
->ElementCount
== 0) {
3251 // Skip if there is no RequestElement
3257 // Request current settings from Configuration Driver
3259 Status
= FormSet
->ConfigAccess
->ExtractConfig (
3260 FormSet
->ConfigAccess
,
3261 Storage
->ConfigRequest
,
3265 if (EFI_ERROR (Status
)) {
3270 // Convert Result from <ConfigAltResp> to <ConfigResp>
3272 StrPtr
= StrStr (Result
, L
"ALTCFG");
3273 if (StrPtr
!= NULL
) {
3277 Status
= ConfigRespToStorage (Storage
, Result
);
3284 Copy uncommitted data from source Storage to destination Storage.
3286 @param Dst Target Storage for uncommitted data.
3287 @param Src Source Storage for uncommitted data.
3289 @retval EFI_SUCCESS The function completed successfully.
3290 @retval EFI_INVALID_PARAMETER Source and destination Storage is not the same type.
3295 IN OUT FORMSET_STORAGE
*Dst
,
3296 IN FORMSET_STORAGE
*Src
3300 NAME_VALUE_NODE
*Node
;
3302 if ((Dst
->Type
!= Src
->Type
) || (Dst
->Size
!= Src
->Size
)) {
3303 return EFI_INVALID_PARAMETER
;
3306 switch (Src
->Type
) {
3307 case EFI_HII_VARSTORE_BUFFER
:
3308 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER
:
3309 CopyMem (Dst
->EditBuffer
, Src
->EditBuffer
, Src
->Size
);
3310 CopyMem (Dst
->Buffer
, Src
->Buffer
, Src
->Size
);
3313 case EFI_HII_VARSTORE_NAME_VALUE
:
3314 Link
= GetFirstNode (&Src
->NameValueListHead
);
3315 while (!IsNull (&Src
->NameValueListHead
, Link
)) {
3316 Node
= NAME_VALUE_NODE_FROM_LINK (Link
);
3318 SetValueByName (Dst
, Node
->Name
, Node
->EditValue
, TRUE
);
3319 SetValueByName (Dst
, Node
->Name
, Node
->Value
, FALSE
);
3321 Link
= GetNextNode (&Src
->NameValueListHead
, Link
);
3325 case EFI_HII_VARSTORE_EFI_VARIABLE
:
3335 Get current setting of Questions.
3337 @param FormSet FormSet data structure.
3339 @retval EFI_SUCCESS The function completed successfully.
3343 InitializeCurrentSetting (
3344 IN OUT FORM_BROWSER_FORMSET
*FormSet
3349 FORMSET_STORAGE
*Storage
;
3350 FORMSET_STORAGE
*StorageSrc
;
3351 FORMSET_STORAGE
*OldStorage
;
3352 FORM_BROWSER_FORM
*Form
;
3353 FORM_BROWSER_FORM
*Form2
;
3357 // Extract default from IFR binary
3359 ExtractDefault (FormSet
, NULL
, EFI_HII_DEFAULT_CLASS_STANDARD
, FormSetLevel
);
3360 UpdateNvInfoInForm (FormSet
, FALSE
);
3363 // Request current settings from Configuration Driver
3365 Link
= GetFirstNode (&FormSet
->StorageListHead
);
3366 while (!IsNull (&FormSet
->StorageListHead
, Link
)) {
3367 Storage
= FORMSET_STORAGE_FROM_LINK (Link
);
3370 if (gOldFormSet
!= NULL
) {
3372 // Try to find the Storage in backup formset gOldFormSet
3374 Link2
= GetFirstNode (&gOldFormSet
->StorageListHead
);
3375 while (!IsNull (&gOldFormSet
->StorageListHead
, Link2
)) {
3376 StorageSrc
= FORMSET_STORAGE_FROM_LINK (Link2
);
3378 if (StorageSrc
->VarStoreId
== Storage
->VarStoreId
) {
3379 OldStorage
= StorageSrc
;
3383 Link2
= GetNextNode (&gOldFormSet
->StorageListHead
, Link2
);
3387 if (OldStorage
== NULL
) {
3389 // Storage is not found in backup formset, request it from ConfigDriver
3391 Status
= LoadStorage (FormSet
, Storage
);
3393 // Now Edit Buffer is filled with default values(lower priority) and current
3394 // settings(higher priority), sychronize it to shadow Buffer
3396 if (!EFI_ERROR (Status
)) {
3397 SynchronizeStorage (Storage
, TRUE
);
3401 // Storage found in backup formset, use it
3403 Status
= CopyStorage (Storage
, OldStorage
);
3406 Link
= GetNextNode (&FormSet
->StorageListHead
, Link
);
3410 // If has old formset, get the old nv update status.
3412 if (gOldFormSet
!= NULL
) {
3413 Link
= GetFirstNode (&FormSet
->FormListHead
);
3414 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
3415 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
3417 Link2
= GetFirstNode (&gOldFormSet
->FormListHead
);
3418 while (!IsNull (&gOldFormSet
->FormListHead
, Link2
)) {
3419 Form2
= FORM_BROWSER_FORM_FROM_LINK (Link2
);
3421 if (Form
->FormId
== Form2
->FormId
) {
3422 Form
->NvUpdateRequired
= Form2
->NvUpdateRequired
;
3426 Link2
= GetNextNode (&gOldFormSet
->FormListHead
, Link2
);
3428 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
3437 Fetch the Ifr binary data of a FormSet.
3439 @param Handle PackageList Handle
3440 @param FormSetGuid On input, GUID or class GUID of a formset. If not
3441 specified (NULL or zero GUID), take the first
3442 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
3443 found in package list.
3444 On output, GUID of the formset found(if not NULL).
3445 @param BinaryLength The length of the FormSet IFR binary.
3446 @param BinaryData The buffer designed to receive the FormSet.
3448 @retval EFI_SUCCESS Buffer filled with the requested FormSet.
3449 BufferLength was updated.
3450 @retval EFI_INVALID_PARAMETER The handle is unknown.
3451 @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot
3452 be found with the requested FormId.
3457 IN EFI_HII_HANDLE Handle
,
3458 IN OUT EFI_GUID
*FormSetGuid
,
3459 OUT UINTN
*BinaryLength
,
3460 OUT UINT8
**BinaryData
3464 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
3470 UINT32 PackageListLength
;
3471 EFI_HII_PACKAGE_HEADER PackageHeader
;
3473 UINT8 NumberOfClassGuid
;
3474 BOOLEAN ClassGuidMatch
;
3475 EFI_GUID
*ClassGuid
;
3476 EFI_GUID
*ComparingGuid
;
3480 ZeroMem (&PackageHeader
, sizeof (EFI_HII_PACKAGE_HEADER
));
3483 // if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
3485 if (FormSetGuid
== NULL
) {
3486 ComparingGuid
= &gZeroGuid
;
3488 ComparingGuid
= FormSetGuid
;
3492 // Get HII PackageList
3495 HiiPackageList
= NULL
;
3496 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
3497 if (Status
== EFI_BUFFER_TOO_SMALL
) {
3498 HiiPackageList
= AllocatePool (BufferSize
);
3499 ASSERT (HiiPackageList
!= NULL
);
3501 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
3503 if (EFI_ERROR (Status
)) {
3506 ASSERT (HiiPackageList
!= NULL
);
3509 // Get Form package from this HII package List
3511 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
3513 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
3515 ClassGuidMatch
= FALSE
;
3516 while (Offset
< PackageListLength
) {
3517 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
3518 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
3520 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
3522 // Search FormSet in this Form Package
3524 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
3525 while (Offset2
< PackageHeader
.Length
) {
3526 OpCodeData
= Package
+ Offset2
;
3528 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
3530 // Try to compare against formset GUID
3532 if (CompareGuid (FormSetGuid
, &gZeroGuid
) ||
3533 CompareGuid (ComparingGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))) {
3537 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
3539 // Try to compare against formset class GUID
3541 NumberOfClassGuid
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
3542 ClassGuid
= (EFI_GUID
*) (OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
3543 for (Index
= 0; Index
< NumberOfClassGuid
; Index
++) {
3544 if (CompareGuid (ComparingGuid
, ClassGuid
+ Index
)) {
3545 ClassGuidMatch
= TRUE
;
3549 if (ClassGuidMatch
) {
3552 } else if (ComparingGuid
== &gEfiHiiPlatformSetupFormsetGuid
) {
3553 ClassGuidMatch
= TRUE
;
3558 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
3561 if (Offset2
< PackageHeader
.Length
) {
3563 // Target formset found
3569 Offset
+= PackageHeader
.Length
;
3572 if (Offset
>= PackageListLength
) {
3574 // Form package not found in this Package List
3576 FreePool (HiiPackageList
);
3577 return EFI_NOT_FOUND
;
3580 if (FormSetGuid
!= NULL
) {
3582 // Return the FormSet GUID
3584 CopyMem (FormSetGuid
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Guid
, sizeof (EFI_GUID
));
3588 // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes
3589 // in this FormSet; So, here just simply copy the data from start of a FormSet to the end
3590 // of the Form Package.
3592 *BinaryLength
= PackageHeader
.Length
- Offset2
;
3593 *BinaryData
= AllocateCopyPool (*BinaryLength
, OpCodeData
);
3595 FreePool (HiiPackageList
);
3597 if (*BinaryData
== NULL
) {
3598 return EFI_OUT_OF_RESOURCES
;
3606 Initialize the internal data structure of a FormSet.
3608 @param Handle PackageList Handle
3609 @param FormSetGuid On input, GUID or class GUID of a formset. If not
3610 specified (NULL or zero GUID), take the first
3611 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
3612 found in package list.
3613 On output, GUID of the formset found(if not NULL).
3614 @param FormSet FormSet data structure.
3616 @retval EFI_SUCCESS The function completed successfully.
3617 @retval EFI_NOT_FOUND The specified FormSet could not be found.
3622 IN EFI_HII_HANDLE Handle
,
3623 IN OUT EFI_GUID
*FormSetGuid
,
3624 OUT FORM_BROWSER_FORMSET
*FormSet
3628 EFI_HANDLE DriverHandle
;
3631 Status
= GetIfrBinaryData (Handle
, FormSetGuid
, &FormSet
->IfrBinaryLength
, &FormSet
->IfrBinaryData
);
3632 if (EFI_ERROR (Status
)) {
3636 FormSet
->Signature
= FORM_BROWSER_FORMSET_SIGNATURE
;
3637 FormSet
->HiiHandle
= Handle
;
3638 CopyMem (&FormSet
->Guid
, FormSetGuid
, sizeof (EFI_GUID
));
3641 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
3643 Status
= mHiiDatabase
->GetPackageListHandle (mHiiDatabase
, Handle
, &DriverHandle
);
3644 if (EFI_ERROR (Status
)) {
3647 FormSet
->DriverHandle
= DriverHandle
;
3648 Status
= gBS
->HandleProtocol (
3650 &gEfiHiiConfigAccessProtocolGuid
,
3651 (VOID
**) &FormSet
->ConfigAccess
3653 if (EFI_ERROR (Status
)) {
3655 // Configuration Driver don't attach ConfigAccess protocol to its HII package
3656 // list, then there will be no configuration action required
3658 FormSet
->ConfigAccess
= NULL
;
3662 // Parse the IFR binary OpCodes
3664 Status
= ParseOpCodes (FormSet
);
3665 if (EFI_ERROR (Status
)) {
3670 // Set VFR type by FormSet SubClass field
3672 gClassOfVfr
= FORMSET_CLASS_PLATFORM_SETUP
;
3673 if (FormSet
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) {
3674 gClassOfVfr
= FORMSET_CLASS_FRONT_PAGE
;
3678 // Set VFR type by FormSet class guid
3680 for (Index
= 0; Index
< 3; Index
++) {
3681 if (CompareGuid (&FormSet
->ClassGuid
[Index
], &gEfiHiiPlatformSetupFormsetGuid
)) {
3682 gClassOfVfr
|= FORMSET_CLASS_PLATFORM_SETUP
;
3687 if ((gClassOfVfr
& FORMSET_CLASS_FRONT_PAGE
) == FORMSET_CLASS_FRONT_PAGE
) {
3688 gFrontPageHandle
= FormSet
->HiiHandle
;
3689 gFunctionKeySetting
= NONE_FUNCTION_KEY_SETTING
;
3693 // Match GUID to find out the function key setting. If match fail, use the default setting.
3695 for (Index
= 0; Index
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index
++) {
3696 if (CompareGuid (&FormSet
->Guid
, &(gFunctionKeySettingTable
[Index
].FormSetGuid
))) {
3698 // Update the function key setting.
3700 gFunctionKeySetting
= gFunctionKeySettingTable
[Index
].KeySetting
;
3709 Save globals used by previous call to SendForm(). SendForm() may be called from
3710 HiiConfigAccess.Callback(), this will cause SendForm() be reentried.
3711 So, save globals of previous call to SendForm() and restore them upon exit.
3715 SaveBrowserContext (
3719 BROWSER_CONTEXT
*Context
;
3721 gBrowserContextCount
++;
3722 if (gBrowserContextCount
== 1) {
3724 // This is not reentry of SendForm(), no context to save
3729 Context
= AllocatePool (sizeof (BROWSER_CONTEXT
));
3730 ASSERT (Context
!= NULL
);
3732 Context
->Signature
= BROWSER_CONTEXT_SIGNATURE
;
3735 // Save FormBrowser context
3737 Context
->BannerData
= gBannerData
;
3738 Context
->ClassOfVfr
= gClassOfVfr
;
3739 Context
->FunctionKeySetting
= gFunctionKeySetting
;
3740 Context
->ResetRequired
= gResetRequired
;
3741 Context
->Direction
= gDirection
;
3742 Context
->EnterString
= gEnterString
;
3743 Context
->EnterCommitString
= gEnterCommitString
;
3744 Context
->EnterEscapeString
= gEnterEscapeString
;
3745 Context
->EscapeString
= gEscapeString
;
3746 Context
->MoveHighlight
= gMoveHighlight
;
3747 Context
->MakeSelection
= gMakeSelection
;
3748 Context
->DecNumericInput
= gDecNumericInput
;
3749 Context
->HexNumericInput
= gHexNumericInput
;
3750 Context
->ToggleCheckBox
= gToggleCheckBox
;
3751 Context
->PromptForData
= gPromptForData
;
3752 Context
->PromptForPassword
= gPromptForPassword
;
3753 Context
->PromptForNewPassword
= gPromptForNewPassword
;
3754 Context
->ConfirmPassword
= gConfirmPassword
;
3755 Context
->ConfirmError
= gConfirmError
;
3756 Context
->PassowordInvalid
= gPassowordInvalid
;
3757 Context
->PressEnter
= gPressEnter
;
3758 Context
->EmptyString
= gEmptyString
;
3759 Context
->AreYouSure
= gAreYouSure
;
3760 Context
->YesResponse
= gYesResponse
;
3761 Context
->NoResponse
= gNoResponse
;
3762 Context
->MiniString
= gMiniString
;
3763 Context
->PlusString
= gPlusString
;
3764 Context
->MinusString
= gMinusString
;
3765 Context
->AdjustNumber
= gAdjustNumber
;
3766 Context
->SaveChanges
= gSaveChanges
;
3767 Context
->OptionMismatch
= gOptionMismatch
;
3768 Context
->FormSuppress
= gFormSuppress
;
3769 Context
->PromptBlockWidth
= gPromptBlockWidth
;
3770 Context
->OptionBlockWidth
= gOptionBlockWidth
;
3771 Context
->HelpBlockWidth
= gHelpBlockWidth
;
3772 Context
->OldFormSet
= gOldFormSet
;
3773 Context
->MenuRefreshHead
= gMenuRefreshHead
;
3775 CopyMem (&Context
->ScreenDimensions
, &gScreenDimensions
, sizeof (gScreenDimensions
));
3776 CopyMem (&Context
->MenuOption
, &gMenuOption
, sizeof (gMenuOption
));
3779 // Insert to FormBrowser context list
3781 InsertHeadList (&gBrowserContextList
, &Context
->Link
);
3786 Restore globals used by previous call to SendForm().
3790 RestoreBrowserContext (
3795 BROWSER_CONTEXT
*Context
;
3797 ASSERT (gBrowserContextCount
!= 0);
3798 gBrowserContextCount
--;
3799 if (gBrowserContextCount
== 0) {
3801 // This is not reentry of SendForm(), no context to restore
3806 ASSERT (!IsListEmpty (&gBrowserContextList
));
3808 Link
= GetFirstNode (&gBrowserContextList
);
3809 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
3812 // Restore FormBrowser context
3814 gBannerData
= Context
->BannerData
;
3815 gClassOfVfr
= Context
->ClassOfVfr
;
3816 gFunctionKeySetting
= Context
->FunctionKeySetting
;
3817 gResetRequired
= Context
->ResetRequired
;
3818 gDirection
= Context
->Direction
;
3819 gEnterString
= Context
->EnterString
;
3820 gEnterCommitString
= Context
->EnterCommitString
;
3821 gEnterEscapeString
= Context
->EnterEscapeString
;
3822 gEscapeString
= Context
->EscapeString
;
3823 gMoveHighlight
= Context
->MoveHighlight
;
3824 gMakeSelection
= Context
->MakeSelection
;
3825 gDecNumericInput
= Context
->DecNumericInput
;
3826 gHexNumericInput
= Context
->HexNumericInput
;
3827 gToggleCheckBox
= Context
->ToggleCheckBox
;
3828 gPromptForData
= Context
->PromptForData
;
3829 gPromptForPassword
= Context
->PromptForPassword
;
3830 gPromptForNewPassword
= Context
->PromptForNewPassword
;
3831 gConfirmPassword
= Context
->ConfirmPassword
;
3832 gConfirmError
= Context
->ConfirmError
;
3833 gPassowordInvalid
= Context
->PassowordInvalid
;
3834 gPressEnter
= Context
->PressEnter
;
3835 gEmptyString
= Context
->EmptyString
;
3836 gAreYouSure
= Context
->AreYouSure
;
3837 gYesResponse
= Context
->YesResponse
;
3838 gNoResponse
= Context
->NoResponse
;
3839 gMiniString
= Context
->MiniString
;
3840 gPlusString
= Context
->PlusString
;
3841 gMinusString
= Context
->MinusString
;
3842 gAdjustNumber
= Context
->AdjustNumber
;
3843 gSaveChanges
= Context
->SaveChanges
;
3844 gOptionMismatch
= Context
->OptionMismatch
;
3845 gFormSuppress
= Context
->FormSuppress
;
3846 gPromptBlockWidth
= Context
->PromptBlockWidth
;
3847 gOptionBlockWidth
= Context
->OptionBlockWidth
;
3848 gHelpBlockWidth
= Context
->HelpBlockWidth
;
3849 gOldFormSet
= Context
->OldFormSet
;
3850 gMenuRefreshHead
= Context
->MenuRefreshHead
;
3852 CopyMem (&gScreenDimensions
, &Context
->ScreenDimensions
, sizeof (gScreenDimensions
));
3853 CopyMem (&gMenuOption
, &Context
->MenuOption
, sizeof (gMenuOption
));
3856 // Remove from FormBrowser context list
3858 RemoveEntryList (&Context
->Link
);
3859 gBS
->FreePool (Context
);
3863 Find the matched FormSet context in the backup maintain list based on HiiHandle.
3865 @param Handle The Hii Handle.
3867 @return the found FormSet context. If no found, NULL will return.
3870 FORM_BROWSER_FORMSET
*
3871 GetFormSetFromHiiHandle (
3872 EFI_HII_HANDLE Handle
3876 FORM_BROWSER_FORMSET
*FormSet
;
3878 Link
= GetFirstNode (&gBrowserFormSetList
);
3879 while (!IsNull (&gBrowserFormSetList
, Link
)) {
3880 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
3881 if (FormSet
->HiiHandle
== Handle
) {
3884 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
3891 Check whether the input HII handle is the FormSet that is being used.
3893 @param Handle The Hii Handle.
3895 @retval TRUE HII handle is being used.
3896 @retval FALSE HII handle is not being used.
3900 IsHiiHandleInBrowserContext (
3901 EFI_HII_HANDLE Handle
3905 BROWSER_CONTEXT
*Context
;
3908 // HiiHandle is Current FormSet.
3910 if ((gOldFormSet
!= NULL
) && (gOldFormSet
->HiiHandle
== Handle
)) {
3915 // Check whether HiiHandle is in BrowserContext.
3917 Link
= GetFirstNode (&gBrowserContextList
);
3918 while (!IsNull (&gBrowserContextList
, Link
)) {
3919 Context
= BROWSER_CONTEXT_FROM_LINK (Link
);
3920 if (Context
->OldFormSet
->HiiHandle
== Handle
) {
3922 // HiiHandle is in BrowserContext
3926 Link
= GetNextNode (&gBrowserContextList
, Link
);
3933 Find the registered HotKey based on KeyData.
3935 @param[in] KeyData A pointer to a buffer that describes the keystroke
3936 information for the hot key.
3938 @return The registered HotKey context. If no found, NULL will return.
3941 GetHotKeyFromRegisterList (
3942 IN EFI_INPUT_KEY
*KeyData
3946 BROWSER_HOT_KEY
*HotKey
;
3948 Link
= GetFirstNode (&gBrowserHotKeyList
);
3949 while (!IsNull (&gBrowserHotKeyList
, Link
)) {
3950 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
3951 if (HotKey
->KeyData
->ScanCode
== KeyData
->ScanCode
) {
3954 Link
= GetNextNode (&gBrowserHotKeyList
, Link
);
3961 Configure what scope the hot key will impact.
3962 All hot keys have the same scope. The mixed hot keys with the different level are not supported.
3963 If no scope is set, the default scope will be FormSet level.
3964 After all registered hot keys are removed, previous Scope can reset to another level.
3966 @param[in] Scope Scope level to be set.
3968 @retval EFI_SUCCESS Scope is set correctly.
3969 @retval EFI_INVALID_PARAMETER Scope is not the valid value specified in BROWSER_SETTING_SCOPE.
3970 @retval EFI_UNSPPORTED Scope level is different from current one that the registered hot keys have.
3976 IN BROWSER_SETTING_SCOPE Scope
3979 if (Scope
>= MaxLevel
) {
3980 return EFI_INVALID_PARAMETER
;
3984 // When no hot key registered in system or on the first setting,
3985 // Scope can be set.
3987 if (mBrowserScopeFirstSet
|| IsListEmpty (&gBrowserHotKeyList
)) {
3988 gBrowserSettingScope
= Scope
;
3989 mBrowserScopeFirstSet
= FALSE
;
3990 } else if (Scope
!= gBrowserSettingScope
) {
3991 return EFI_UNSUPPORTED
;
3998 Register the hot key with its browser action, or unregistered the hot key.
3999 Only support hot key that is not printable character (control key, function key, etc.).
4000 If the action value is zero, the hot key will be unregistered if it has been registered.
4001 If the same hot key has been registered, the new action and help string will override the previous ones.
4003 @param[in] KeyData A pointer to a buffer that describes the keystroke
4004 information for the hot key. Its type is EFI_INPUT_KEY to
4005 be supported by all ConsoleIn devices.
4006 @param[in] Action Action value that describes what action will be trigged when the hot key is pressed.
4007 @param[in] DefaultId Specifies the type of defaults to retrieve, which is only for DEFAULT action.
4008 @param[in] HelpString Help string that describes the hot key information.
4009 Its value may be NULL for the unregistered hot key.
4011 @retval EFI_SUCCESS Hot key is registered or unregistered.
4012 @retval EFI_INVALID_PARAMETER KeyData is NULL or HelpString is NULL on register.
4013 @retval EFI_NOT_FOUND KeyData is not found to be unregistered.
4014 @retval EFI_UNSUPPORTED Key represents a printable character. It is conflicted with Browser.
4019 IN EFI_INPUT_KEY
*KeyData
,
4021 IN UINT16 DefaultId
,
4022 IN EFI_STRING HelpString OPTIONAL
4025 BROWSER_HOT_KEY
*HotKey
;
4028 // Check input parameters.
4030 if (KeyData
== NULL
|| KeyData
->UnicodeChar
!= CHAR_NULL
||
4031 (Action
!= BROWSER_ACTION_UNREGISTER
&& HelpString
== NULL
)) {
4032 return EFI_INVALID_PARAMETER
;
4036 // Check whether the input KeyData is in BrowserHotKeyList.
4038 HotKey
= GetHotKeyFromRegisterList (KeyData
);
4041 // Unregister HotKey
4043 if (Action
== BROWSER_ACTION_UNREGISTER
) {
4044 if (HotKey
!= NULL
) {
4046 // The registered HotKey is found.
4047 // Remove it from List, and free its resource.
4049 RemoveEntryList (&HotKey
->Link
);
4050 FreePool (HotKey
->KeyData
);
4051 FreePool (HotKey
->HelpString
);
4055 // The registered HotKey is not found.
4057 return EFI_NOT_FOUND
;
4062 // Register HotKey into List.
4064 if (HotKey
== NULL
) {
4066 // Create new Key, and add it into List.
4068 HotKey
= AllocateZeroPool (sizeof (BROWSER_HOT_KEY
));
4069 ASSERT (HotKey
!= NULL
);
4070 HotKey
->Signature
= BROWSER_HOT_KEY_SIGNATURE
;
4071 HotKey
->KeyData
= AllocateCopyPool (sizeof (EFI_INPUT_KEY
), KeyData
);
4072 InsertTailList (&gBrowserHotKeyList
, &HotKey
->Link
);
4076 // Fill HotKey information.
4078 HotKey
->Action
= Action
;
4079 HotKey
->DefaultId
= DefaultId
;
4080 if (HotKey
->HelpString
!= NULL
) {
4081 FreePool (HotKey
->HelpString
);
4083 HotKey
->HelpString
= AllocateCopyPool (StrSize (HelpString
), HelpString
);
4089 Register Exit handler function.
4090 When more than one handler function is registered, the latter one will override the previous one.
4091 When NULL handler is specified, the previous Exit handler will be unregistered.
4093 @param[in] Handler Pointer to handler function.
4098 RegiserExitHandler (
4099 IN EXIT_HANDLER Handler
4102 ExitHandlerFunction
= Handler
;
4107 Create reminder to let user to choose save or discard the changed browser data.
4108 Caller can use it to actively check the changed browser data.
4110 @retval BROWSER_NO_CHANGES No browser data is changed.
4111 @retval BROWSER_SAVE_CHANGES The changed browser data is saved.
4112 @retval BROWSER_DISCARD_CHANGES The changed browser data is discard.
4122 FORM_BROWSER_FORMSET
*FormSet
;
4123 BOOLEAN IsDataChanged
;
4124 UINT32 DataSavedAction
;
4125 CHAR16
*YesResponse
;
4127 CHAR16
*EmptyString
;
4128 CHAR16
*ChangeReminderString
;
4129 CHAR16
*SaveConfirmString
;
4133 DataSavedAction
= BROWSER_NO_CHANGES
;
4134 IsDataChanged
= FALSE
;
4135 Link
= GetFirstNode (&gBrowserFormSetList
);
4136 while (!IsNull (&gBrowserFormSetList
, Link
)) {
4137 FormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
4138 if (IsNvUpdateRequired (FormSet
)) {
4139 IsDataChanged
= TRUE
;
4142 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
4146 // No data is changed. No save is required.
4148 if (!IsDataChanged
) {
4149 return DataSavedAction
;
4153 // If data is changed, prompt user
4155 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
4157 YesResponse
= GetToken (STRING_TOKEN (ARE_YOU_SURE_YES
), gHiiHandle
);
4158 ASSERT (YesResponse
!= NULL
);
4159 NoResponse
= GetToken (STRING_TOKEN (ARE_YOU_SURE_NO
), gHiiHandle
);
4160 ASSERT (NoResponse
!= NULL
);
4161 EmptyString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
4162 ChangeReminderString
= GetToken (STRING_TOKEN (CHANGE_REMINDER
), gHiiHandle
);
4163 SaveConfirmString
= GetToken (STRING_TOKEN (SAVE_CONFIRM
), gHiiHandle
);
4166 CreateDialog (4, TRUE
, 0, NULL
, &Key
, EmptyString
, ChangeReminderString
, SaveConfirmString
, EmptyString
);
4168 (((Key
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) != (NoResponse
[0] | UPPER_LOWER_CASE_OFFSET
)) &&
4169 ((Key
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) != (YesResponse
[0] | UPPER_LOWER_CASE_OFFSET
))
4173 // If the user hits the YesResponse key
4175 if ((Key
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) == (YesResponse
[0] | UPPER_LOWER_CASE_OFFSET
)) {
4176 SubmitForm (NULL
, NULL
, SystemLevel
);
4177 DataSavedAction
= BROWSER_SAVE_CHANGES
;
4179 DiscardForm (NULL
, NULL
, SystemLevel
);
4180 DataSavedAction
= BROWSER_DISCARD_CHANGES
;
4181 gResetRequired
= FALSE
;
4184 FreePool (YesResponse
);
4185 FreePool (NoResponse
);
4186 FreePool (EmptyString
);
4187 FreePool (SaveConfirmString
);
4188 FreePool (ChangeReminderString
);
4190 return DataSavedAction
;