2 Copyright (c) 2006, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 Entry and initialization module for the browser
24 FUNCTIION_KEY_SETTING gFunctionKeySettingTable
[] = {
44 NONE_FUNCTION_KEY_SETTING
65 NONE_FUNCTION_KEY_SETTING
86 NONE_FUNCTION_KEY_SETTING
89 // BMM File Explorer Formset.
107 NONE_FUNCTION_KEY_SETTING
113 InitializeBinaryStructures (
114 IN EFI_HII_HANDLE
*Handle
,
115 IN BOOLEAN UseDatabase
,
116 IN EFI_IFR_PACKET
*Packet
,
117 IN UINT8
*NvMapOverride
,
118 IN UINTN NumberOfIfrImages
,
119 EFI_FILE_FORM_TAGS
**FileFormTagsHead
124 InitializeTagStructures (
125 IN EFI_IFR_BINARY
*BinaryData
,
126 OUT EFI_FILE_FORM_TAGS
*FileFormTags
132 IN UINTN NumberOfIfrImages
,
133 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
134 IN UINT8
*CallbackData
140 IN EFI_HII_PROTOCOL
*Hii
,
141 IN EFI_HII_HANDLE HiiHandle
,
142 IN EFI_IFR_PACKET
*Packet
,
143 IN EFI_IFR_BINARY
*BinaryData
156 IN EFI_FORM_BROWSER_PROTOCOL
* This
,
157 IN BOOLEAN UseDatabase
,
158 IN EFI_HII_HANDLE
* Handle
,
159 IN UINTN HandleCount
,
160 IN EFI_IFR_PACKET
* Packet
,
161 IN EFI_HANDLE CallbackHandle
,
162 IN UINT8
*NvMapOverride
,
163 IN EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
164 OUT BOOLEAN
*ResetRequired OPTIONAL
170 This is the routine which an external caller uses to direct the browser
171 where to obtain it's information.
175 UseDatabase - If set to TRUE, then all information is retrieved from the HII database handle specified
176 If set to FALSE, then the passed in Packet and CallbackHandle is used and Handle is ignored
178 Handle - A pointer to an array of Handles. If HandleCount > 1 we display a list of the formsets for the handles specified
180 HandleCount - The number of Handles specified in Handle.
182 Packet - Valid only if UseDatabase is FALSE. Packet defines the pages being passed into
183 the browser. This is composed of IFR data as well as String information.
185 CallbackHandle - The handle which contains the calling driver's EFI_FORM_CALLBACK_PROTOCOL interface.
187 ScreenDimenions - This allows the browser to be called so that it occupies a portion of the physical screen instead of
188 dynamically determining the screen dimensions.
190 NvMapOverride - This buffer is used only when there is no NV variable to define the current settings and the caller
191 needs to provide to the browser the current settings for the "fake" NV variable. If used, no saving
192 of an NV variable will be possible. This parameter is also ignored if HandleCount > 1.
198 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
199 EFI_FILE_FORM_TAGS
*FileFormTagsHead
;
200 UI_MENU_OPTION
*Selection
;
201 UI_MENU_OPTION
*AltSelection
;
205 EFI_HII_HANDLE BackupHandle
;
207 ZeroMem (&gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
209 gPreviousValue
= AllocatePool (0x1000);
210 CallbackData
= AllocatePool (0x10000);
211 ASSERT (gPreviousValue
!= NULL
);
212 ASSERT (CallbackData
!= NULL
);
216 // Seed the dimensions in the global
218 gST
->ConOut
->QueryMode (
220 gST
->ConOut
->Mode
->Mode
,
221 &gScreenDimensions
.RightColumn
,
222 &gScreenDimensions
.BottomRow
225 if (ScreenDimensions
!= NULL
) {
227 // Check local dimension vs. global dimension.
229 if ((gScreenDimensions
.RightColumn
< ScreenDimensions
->RightColumn
) ||
230 (gScreenDimensions
.BottomRow
< ScreenDimensions
->BottomRow
)
232 return EFI_INVALID_PARAMETER
;
235 // Local dimension validation.
237 if ((ScreenDimensions
->RightColumn
> ScreenDimensions
->LeftColumn
) &&
238 (ScreenDimensions
->BottomRow
> ScreenDimensions
->TopRow
) &&
239 ((ScreenDimensions
->RightColumn
- ScreenDimensions
->LeftColumn
) > 2) &&
241 (ScreenDimensions
->BottomRow
- ScreenDimensions
->TopRow
) > STATUS_BAR_HEIGHT
+
242 SCROLL_ARROW_HEIGHT
*
244 FRONT_PAGE_HEADER_HEIGHT
+
249 CopyMem (&gScreenDimensions
, ScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
251 return EFI_INVALID_PARAMETER
;
256 gOptionBlockWidth
= (CHAR16
) ((gScreenDimensions
.RightColumn
- gScreenDimensions
.LeftColumn
) / 3);
257 gHelpBlockWidth
= gOptionBlockWidth
;
258 gPromptBlockWidth
= gOptionBlockWidth
;
261 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
263 InitializeBrowserStrings ();
265 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
266 gClassOfVfr
= EFI_SETUP_APPLICATION_SUBCLASS
;
267 gResetRequired
= FALSE
;
268 gExitRequired
= FALSE
;
269 gSaveRequired
= FALSE
;
270 gNvUpdateRequired
= FALSE
;
274 BackupHandle
= *Handle
;
275 gMenuRefreshHead
= NULL
;
276 ASSERT (CallbackData
);
277 ZeroMem (CallbackData
, 0x10000);
280 // We can recurse through this and might need to re-allocate this particular buffer
282 if (gPreviousValue
== NULL
) {
283 gPreviousValue
= AllocatePool (0x1000);
284 ASSERT (gPreviousValue
!= NULL
);
290 if (CallbackHandle
!= NULL
) {
292 // Retrieve the Callback protocol interface
294 Status
= gBS
->HandleProtocol (
296 &gEfiFormCallbackProtocolGuid
,
297 (VOID
**) &FormCallback
300 if (EFI_ERROR (Status
)) {
301 gBS
->FreePool (CallbackData
);
308 // Initializes all the internal state structures for all IFR images in system
310 Status
= InitializeBinaryStructures (Handle
, UseDatabase
, Packet
, NvMapOverride
, HandleCount
, &FileFormTagsHead
);
312 if (EFI_ERROR (Status
)) {
313 gBS
->FreePool (CallbackData
);
317 // Beginning of the Presentation of the Data
319 if (UseDatabase
&& (HandleCount
> 1)) {
320 Selection
= DisplayHomePage (HandleCount
, FileFormTagsHead
, CallbackData
);
323 // If passing something specific, we know there is only one Ifr
325 Selection
= AllocateZeroPool (sizeof (UI_MENU_OPTION
));
326 ASSERT (Selection
!= NULL
);
327 Selection
->IfrNumber
= 0;
328 Selection
->Handle
= Handle
[0];
334 if (UseDatabase
&& (HandleCount
> 1)) {
335 if (Selection
== NULL
) {
336 gBS
->FreePool (CallbackData
);
341 // Launch the setup browser with the user's selection information
343 AltSelection
= SetupBrowser (Selection
, Callback
, FileFormTagsHead
, CallbackData
);
346 // If the caller cares about Reset status, we can return to the caller if something happened that required a reset
348 if (ResetRequired
!= NULL
) {
349 *ResetRequired
= gResetRequired
;
352 if (Callback
&& (AltSelection
!= NULL
)) {
353 if ((FormCallback
!= NULL
) && (FormCallback
->Callback
!= NULL
)) {
354 Status
= FormCallback
->Callback (
356 AltSelection
->ThisTag
->Key
,
358 (EFI_HII_CALLBACK_PACKET
**) &Packet
363 *Handle
= BackupHandle
;
365 if (EFI_ERROR (Status
)) {
366 gBS
->FreePool (CallbackData
);
370 if (Callback
&& (AltSelection
== NULL
)) {
371 gBS
->FreePool (CallbackData
);
375 if (UseDatabase
&& (HandleCount
> 1)) {
378 if (gBinaryDataHead
->UnRegisterOnExit
) {
379 Hii
->RemovePack (Hii
, Handle
[0]);
383 ((AltSelection
->ThisTag
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) ||
384 (AltSelection
->ThisTag
->SubClass
== EFI_SINGLE_USE_SUBCLASS
))) {
386 // If this is the FrontPage, return after every selection
388 gBS
->FreePool (Selection
);
392 // Clean up the allocated data buffers
394 FreeData (FileFormTagsHead
, NULL
, NULL
);
396 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
397 gST
->ConOut
->ClearScreen (gST
->ConOut
);
399 gBS
->FreePool (CallbackData
);
403 gBS
->FreePool (Selection
);
407 // Clean up the allocated data buffers
409 FreeData (FileFormTagsHead
, NULL
, NULL
);
411 gST
->ConOut
->ClearScreen (gST
->ConOut
);
414 gBS
->FreePool (CallbackData
);
419 } while (!EFI_ERROR (Status
));
421 gBS
->FreePool (CallbackData
);
428 IN EFI_HANDLE ImageHandle
,
429 IN EFI_SYSTEM_TABLE
*SystemTable
437 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
440 EFI_SUCCESS - Setup loaded.
446 EFI_FORM_CONFIGURATION_DATA
*FormData
;
447 EFI_FORM_BROWSER_PROTOCOL
*FormBrowser
;
449 EFI_HII_PACKAGES
*PackageList
;
452 // There will be only one FormConfig in the system
453 // If there is another out there, someone is trying to install us
454 // again. Fail that scenario.
456 Status
= gBS
->LocateProtocol (
457 &gEfiFormBrowserProtocolGuid
,
459 (VOID
**) &FormBrowser
465 // If there was no error, assume there is an installation and fail to load
467 if (!EFI_ERROR (Status
)) {
468 return EFI_DEVICE_ERROR
;
471 FormData
= AllocatePool (sizeof (EFI_FORM_CONFIGURATION_DATA
));
473 if (FormData
== NULL
) {
474 return EFI_OUT_OF_RESOURCES
;
479 FormData
->Signature
= EFI_FORM_DATA_SIGNATURE
;
480 FormData
->FormConfig
.SendForm
= SendForm
;
481 FormData
->FormConfig
.CreatePopUp
= CreateDialog
;
484 // There should only be one HII image
486 Status
= gBS
->LocateProtocol (
487 &gEfiHiiProtocolGuid
,
489 (VOID
**) &FormData
->Hii
492 ASSERT_EFI_ERROR (Status
);
496 PackageList
= PreparePackages (1, &gEfiFormBrowserProtocolGuid
, SetupBrowserStrings
);
498 Status
= Hii
->NewPack (Hii
, PackageList
, &gHiiHandle
);
500 gBS
->FreePool (PackageList
);
503 // Install protocol interface
506 Status
= gBS
->InstallProtocolInterface (
508 &gEfiFormBrowserProtocolGuid
,
509 EFI_NATIVE_INTERFACE
,
510 &FormData
->FormConfig
513 ASSERT_EFI_ERROR (Status
);
515 BannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
516 ASSERT (BannerData
!= NULL
);
518 Status
= InstallPrint ();
525 IN UINT8
*RawFormSet
,
527 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
528 IN UINT16 CurrentVariable
533 Initialize question tag's members.
536 Tag - Pointer of the current EFI_TAG structure.
537 RawFormSet - Pointer of the formset raw data.
538 Index - Offset of the current opcode in the Ifr raw data.
539 FileFormTags - Pointer of current EFI_FILE_FORM_TAGS structure.
540 CurrentVariable - Current variable number.
546 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
548 Tag
->NumberOfLines
= 1;
549 Tag
->VariableNumber
= CurrentVariable
;
550 CopyMem (&Tag
->Id
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
551 CopyMem (&Tag
->StorageStart
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
552 CopyMem (&Tag
->StorageWidth
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Width
, sizeof (UINT8
));
553 CopyMem (&Tag
->Text
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Prompt
, sizeof (UINT16
));
554 CopyMem (&Tag
->Help
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Help
, sizeof (UINT16
));
556 VariableDefinition
= FileFormTags
->VariableDefinitions
;
558 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
560 // Have we found the correct variable for the request?
562 if (CurrentVariable
== VariableDefinition
->VariableId
) {
563 if (VariableDefinition
->VariableSize
< (UINTN
) (Tag
->StorageStart
+ Tag
->StorageWidth
)) {
564 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ Tag
->StorageWidth
);
567 if (VariableDefinition
->NvRamMap
!= NULL
) {
569 // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
570 // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
572 if (Tag
->StorageWidth
== (UINT16
) 1) {
573 CopyMem (&Tag
->Value
, &VariableDefinition
->NvRamMap
[Tag
->StorageStart
], sizeof (UINT16
));
576 if (Tag
->StorageWidth
== (UINT16
) 2) {
579 VariableDefinition
->NvRamMap
[Tag
->StorageStart
] +
580 (VariableDefinition
->NvRamMap
[Tag
->StorageStart
+ 1] * 0x100)
582 CopyMem (&Tag
->Value
, &Index
, sizeof (UINT16
));
586 CopyMem (&Tag
->Value
, &Index
, sizeof (UINT16
));
598 IN UINT8
*RawFormSet
,
600 IN UINT16 NumberOfLines
,
601 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
602 IN UINT16 CurrentVariable
607 Initialize numeric tag's members.
610 Tag - Pointer of the current EFI_TAG structure.
611 RawFormSet - Pointer of the formset raw data.
612 Index - Offset of the current opcode in the Ifr raw data.
613 NumberOfLines - Number of lines this opcode occupied.
614 FileFormTags - Pointer of current EFI_FILE_FORM_TAGS structure.
615 CurrentVariable - Current variable number.
621 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
623 Tag
->NumberOfLines
= NumberOfLines
;
624 Tag
->VariableNumber
= CurrentVariable
;
625 CopyMem (&Tag
->Id
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
626 CopyMem (&Tag
->StorageStart
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
627 CopyMem (&Tag
->StorageWidth
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Width
, sizeof (UINT8
));
628 CopyMem (&Tag
->Text
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Prompt
, sizeof (UINT16
));
629 CopyMem (&Tag
->Help
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Help
, sizeof (UINT16
));
630 CopyMem (&Tag
->Minimum
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Minimum
, sizeof (UINT16
));
631 CopyMem (&Tag
->Maximum
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Maximum
, sizeof (UINT16
));
632 CopyMem (&Tag
->Step
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Step
, sizeof (UINT16
));
633 CopyMem (&Tag
->Default
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Default
, sizeof (UINT16
));
634 Tag
->ResetRequired
= (BOOLEAN
) (((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Flags
& EFI_IFR_FLAG_RESET_REQUIRED
);
636 VariableDefinition
= FileFormTags
->VariableDefinitions
;
638 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
640 // Have we found the correct variable for the request?
642 if (CurrentVariable
== VariableDefinition
->VariableId
) {
643 if (VariableDefinition
->VariableSize
<= (UINTN
) (Tag
->StorageStart
+ Tag
->StorageWidth
)) {
644 if (Tag
->StorageWidth
== 0) {
645 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ 2);
647 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ Tag
->StorageWidth
);
651 if (VariableDefinition
->NvRamMap
!= NULL
) {
653 // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
654 // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
656 if (Tag
->StorageWidth
== (UINT16
) 1) {
657 CopyMem (&Tag
->Value
, &VariableDefinition
->NvRamMap
[Tag
->StorageStart
], sizeof (UINT16
));
660 if (Tag
->StorageWidth
== (UINT16
) 2) {
663 VariableDefinition
->NvRamMap
[Tag
->StorageStart
] +
664 (VariableDefinition
->NvRamMap
[Tag
->StorageStart
+ 1] * 0x100)
666 CopyMem (&Tag
->Value
, &Index
, sizeof (UINT16
));
669 CopyMem (&Tag
->Value
, &Tag
->Default
, sizeof (UINT16
));
680 IN UINT8
*RawFormSet
,
681 IN OUT UINT16
*NumberOfTags
687 // Assume on entry we are pointing to an OpCode - reasonably this should
688 // be a FormOp since the purpose is to count the tags in a particular Form.
690 for (Index
= 0; RawFormSet
[Index
] != EFI_IFR_END_FORM_OP
;) {
692 // If we encounter the end of a form set, bail out
694 if (RawFormSet
[Index
] == EFI_IFR_END_FORM_SET_OP
) {
698 // We treat date/time internally as three op-codes
700 if (RawFormSet
[Index
] == EFI_IFR_DATE_OP
|| RawFormSet
[Index
] == EFI_IFR_TIME_OP
) {
701 *NumberOfTags
= (UINT16
) (*NumberOfTags
+ 3);
704 // Assume that we could have no more tags than op-codes
709 Index
= (UINT16
) (Index
+ RawFormSet
[Index
+ 1]);
712 // Increase the tag count by one so it is inclusive of the end_form_op
719 AddNextInconsistentTag (
720 IN OUT EFI_INCONSISTENCY_DATA
**InconsistentTagsPtr
725 Initialize the next inconsistent tag data and add it to the inconsistent tag list.
728 InconsistentTagsPtr - Pointer of the inconsistent tag's pointer.
735 EFI_INCONSISTENCY_DATA
*PreviousInconsistentTags
;
736 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
738 InconsistentTags
= *InconsistentTagsPtr
;
740 // We just hit the end of an inconsistent expression. Let's allocate the ->Next structure
742 InconsistentTags
->Next
= AllocatePool (sizeof (EFI_INCONSISTENCY_DATA
));
743 ASSERT (InconsistentTags
->Next
!= NULL
);
746 // Preserve current Tag entry
748 PreviousInconsistentTags
= InconsistentTags
;
750 InconsistentTags
= InconsistentTags
->Next
;
753 // This will zero on the entry including the ->Next so I don't have to do it
755 ZeroMem (InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
758 // Point our Previous field to the previous entry
760 InconsistentTags
->Previous
= PreviousInconsistentTags
;
762 *InconsistentTagsPtr
= InconsistentTags
;
769 InitializeTagStructures (
770 IN EFI_IFR_BINARY
*BinaryData
,
771 OUT EFI_FILE_FORM_TAGS
*FileFormTags
777 UINT16 QuestionIndex
;
781 EFI_FORM_TAGS
*FormTags
;
782 EFI_FORM_TAGS
*SavedFormTags
;
783 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
784 EFI_VARIABLE_DEFINITION
*VariableDefinitions
;
789 UINT16 CurrentVariable
;
790 UINT16 CurrentVariable2
;
793 // Initialize some Index variable and Status
799 CurrentVariable2
= 0;
802 Status
= EFI_SUCCESS
;
803 FormTags
= &FileFormTags
->FormTags
;
804 FormTags
->Next
= NULL
;
805 if (FileFormTags
->InconsistentTags
== NULL
) {
806 InconsistentTags
= NULL
;
808 InconsistentTags
= FileFormTags
->InconsistentTags
;
811 if (FileFormTags
->VariableDefinitions
== NULL
) {
812 VariableDefinitions
= NULL
;
814 VariableDefinitions
= FileFormTags
->VariableDefinitions
;
817 // RawFormSet now points to the beginning of the forms portion of
818 // the specific IFR Binary.
820 RawFormSet
= (UINT8
*) BinaryData
->FormBinary
;
823 // Determine the number of tags for the first form
825 GetTagCount (&RawFormSet
[0], &NumberOfTags
);
827 SavedFormTags
= FormTags
;
829 if (FormTags
->Tags
!= NULL
) {
832 // Advance FormTags to the last entry
834 for (; FormTags
->Next
!= NULL
; FormTags
= FormTags
->Next
)
838 // Walk through each of the tags and free the IntList allocation
840 for (Index
= 0; Index
< NumberOfTags
; Index
++) {
841 if (FormTags
->Tags
[Index
].IntList
!= NULL
) {
842 gBS
->FreePool (FormTags
->Tags
[Index
].IntList
);
846 gBS
->FreePool (FormTags
->Tags
);
847 gBS
->FreePool (FormTags
->Next
);
848 FormTags
->Next
= NULL
;
849 FormTags
->Tags
= NULL
;
851 FormTags
= SavedFormTags
;
853 } while (FormTags
->Next
!= NULL
);
859 // Test for an allocated buffer. If already allocated this is due to having called this routine
860 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
861 // the tag structure with current values from the NV
863 if (FormTags
->Tags
== NULL
) {
865 // Allocate memory for our tags on the first form
867 FormTags
->Tags
= AllocateZeroPool (NumberOfTags
* sizeof (EFI_TAG
));
868 ASSERT (FormTags
->Tags
);
871 // Test for an allocated buffer. If already allocated this is due to having called this routine
872 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
873 // the tag structure with current values from the NV
875 if (InconsistentTags
== NULL
) {
877 // We just hit the end of an inconsistent expression. Let's allocate the ->Next structure
879 InconsistentTags
= AllocateZeroPool (sizeof (EFI_INCONSISTENCY_DATA
));
880 ASSERT (InconsistentTags
!= NULL
);
882 FileFormTags
->InconsistentTags
= InconsistentTags
;
885 ZeroMem (FormTags
->Tags
, NumberOfTags
* sizeof (EFI_TAG
));
887 for (CurrTag
= 0; RawFormSet
[Index
] != EFI_IFR_END_FORM_SET_OP
; CurrTag
++) {
889 // Operand = IFR OpCode
891 FormTags
->Tags
[CurrTag
].Operand
= RawFormSet
[Index
];
894 // Assume for now 0 lines occupied by this OpCode
896 FormTags
->Tags
[CurrTag
].NumberOfLines
= 0;
898 FormTags
->Tags
[CurrTag
].Class
= Class
;
899 FormTags
->Tags
[CurrTag
].SubClass
= SubClass
;
902 // Determine the length of the Tag so we can later skip to the next tag in the form
904 TagLength
= RawFormSet
[Index
+ 1];
908 // Operate on the Found OpCode
910 switch (RawFormSet
[Index
]) {
912 case EFI_IFR_FORM_OP
:
914 // If there was no variable op-code defined, create a dummy entry for one
916 if (FileFormTags
->VariableDefinitions
== NULL
) {
917 FileFormTags
->VariableDefinitions
= AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION
));
918 ASSERT (FileFormTags
->VariableDefinitions
!= NULL
);
921 &FormTags
->Tags
[CurrTag
],
922 (VOID
*) &RawFormSet
[Index
],
923 FileFormTags
->VariableDefinitions
926 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
930 case EFI_IFR_SUBTITLE_OP
:
931 case EFI_IFR_TEXT_OP
:
933 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
936 case EFI_IFR_VARSTORE_OP
:
937 if (FileFormTags
->VariableDefinitions
== NULL
) {
938 VariableDefinitions
= AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION
));
939 ASSERT (VariableDefinitions
!= NULL
);
940 FileFormTags
->VariableDefinitions
= VariableDefinitions
;
945 &FormTags
->Tags
[CurrTag
],
946 (VOID
*) &RawFormSet
[Index
],
947 FileFormTags
->VariableDefinitions
951 case EFI_IFR_VARSTORE_SELECT_OP
:
952 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
953 CopyMem (&CurrentVariable
, &((EFI_IFR_VARSTORE_SELECT
*) &RawFormSet
[Index
])->VarId
, sizeof (UINT16
));
954 CurrentVariable2
= CurrentVariable
;
957 case EFI_IFR_VARSTORE_SELECT_PAIR_OP
:
958 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
959 CopyMem(&CurrentVariable
, &((EFI_IFR_VARSTORE_SELECT_PAIR
*)&RawFormSet
[Index
])->VarId
, sizeof (UINT16
));
962 &((EFI_IFR_VARSTORE_SELECT_PAIR
*) &RawFormSet
[Index
])->SecondaryVarId
,
967 case EFI_IFR_END_FORM_OP
:
969 // Test for an allocated buffer. If already allocated this is due to having called this routine
970 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
971 // the tag structure with current values from the NV
973 if (FormTags
->Next
== NULL
) {
975 // We just hit the end of a form. Let's allocate the ->Next structure
977 FormTags
->Next
= AllocatePool (sizeof (EFI_FORM_TAGS
));
978 ASSERT (FormTags
->Next
);
981 FormTags
= FormTags
->Next
;
982 ZeroMem (FormTags
, sizeof (EFI_FORM_TAGS
));
985 // Reset the tag count to one
990 // Reset the CurrTag value (it will be incremented, after this case statement
991 // so set to a negative one so that we get the desired effect.) Fish can beat me later.
996 // Determine the number of tags after this form. If this is the last
997 // form, then we will count the endformset and preserve that information
998 // in the tag structure.
1000 GetTagCount (&RawFormSet
[Index
+ TagLength
], &NumberOfTags
);
1003 // Allocate memory for our tags
1005 FormTags
->Tags
= AllocateZeroPool (NumberOfTags
* sizeof (EFI_TAG
));
1006 ASSERT (FormTags
->Tags
);
1010 // Two types of tags constitute the One Of question: a one-of header and
1011 // several one-of options.
1013 case EFI_IFR_ONE_OF_OP
:
1014 case EFI_IFR_ORDERED_LIST_OP
:
1015 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, FileFormTags
, CurrentVariable
);
1018 // Store away the CurrTag since what follows will be the answer that we
1019 // need to place into the appropriate location in the tag array
1022 // record for setting default later
1024 QuestionIndex
= (UINT16
) CurrTag
;
1027 case EFI_IFR_ONE_OF_OPTION_OP
:
1028 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1029 FormTags
->Tags
[QuestionIndex
].Flags
= ((EFI_IFR_ONE_OF_OPTION
*) &RawFormSet
[Index
])->Flags
;
1031 &FormTags
->Tags
[QuestionIndex
].Key
,
1032 &((EFI_IFR_ONE_OF_OPTION
*) &RawFormSet
[Index
])->Key
,
1035 FormTags
->Tags
[QuestionIndex
].ResetRequired
= (BOOLEAN
) (FormTags
->Tags
[QuestionIndex
].Flags
& EFI_IFR_FLAG_RESET_REQUIRED
);
1038 case EFI_IFR_CHECKBOX_OP
:
1039 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, FileFormTags
, CurrentVariable
);
1040 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1043 case EFI_IFR_NUMERIC_OP
:
1044 GetNumericHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, (UINT16
) 1, FileFormTags
, CurrentVariable
);
1045 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1048 case EFI_IFR_DATE_OP
:
1050 // Date elements come in as a Year, Month, Day. We need to process them as a country-based
1051 // Order. It is much easier to do it here than anywhere else.
1053 // For US standards - we want Month/Day/Year, thus we advance "Index" +1, +2, +0 while CurrTag is +0, +1, +2
1056 &FormTags
->Tags
[CurrTag
],
1058 (UINT16
) (Index
+ TagLength
),
1065 // The current language selected + the Date operand
1067 FormTags
->Tags
[CurrTag
+ 1].Operand
= RawFormSet
[Index
];
1069 &FormTags
->Tags
[CurrTag
+ 1],
1071 (UINT16
) (Index
+ TagLength
+ RawFormSet
[Index
+ TagLength
+ 1]),
1078 // The current language selected + the Date operand
1080 FormTags
->Tags
[CurrTag
+ 2].Operand
= RawFormSet
[Index
];
1081 GetNumericHeader (&FormTags
->Tags
[CurrTag
+ 2], RawFormSet
, Index
, (UINT16
) 1, FileFormTags
, CurrentVariable
);
1083 CurrTag
= (INT16
) (CurrTag
+ 2);
1085 Index
= (UINT16
) (Index
+ TagLength
);
1089 TagLength
= RawFormSet
[Index
+ 1];
1090 Index
= (UINT16
) (Index
+ TagLength
);
1094 TagLength
= RawFormSet
[Index
+ 1];
1097 case EFI_IFR_TIME_OP
:
1098 GetNumericHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, (UINT16
) 0, FileFormTags
, CurrentVariable
);
1102 // Override the GetQuestionHeader information - date/time are treated very differently
1104 FormTags
->Tags
[CurrTag
].NumberOfLines
= 1;
1108 // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines
1109 // associated with them, and the third has 1 line to allow to space beyond the choice.
1115 case EFI_IFR_PASSWORD_OP
:
1116 case EFI_IFR_STRING_OP
:
1117 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, FileFormTags
, CurrentVariable
);
1118 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1121 case EFI_IFR_SUPPRESS_IF_OP
:
1122 case EFI_IFR_GRAYOUT_IF_OP
:
1123 InconsistentTags
->Operand
= ((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Header
.OpCode
;
1127 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1128 // Unfortunately 0 is a valid offset value for a QuestionId
1130 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1131 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1134 // Test for an allocated buffer. If already allocated this is due to having called this routine
1135 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1136 // the tag structure with current values from the NV
1138 if (InconsistentTags
->Next
== NULL
) {
1139 AddNextInconsistentTag (&InconsistentTags
);
1143 InconsistentTags
= InconsistentTags
->Next
;
1146 case EFI_IFR_FORM_SET_OP
:
1148 &FormTags
->Tags
[CurrTag
].GuidValue
,
1149 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->Guid
,
1153 &FormTags
->Tags
[CurrTag
].CallbackHandle
,
1154 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->CallbackHandle
,
1155 sizeof (EFI_PHYSICAL_ADDRESS
)
1157 CopyMem (&FormTags
->Tags
[CurrTag
].Class
, &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->Class
, sizeof (UINT8
));
1159 &FormTags
->Tags
[CurrTag
].SubClass
,
1160 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->SubClass
,
1164 &FormTags
->Tags
[CurrTag
].NvDataSize
,
1165 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->NvDataSize
,
1168 Class
= ((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->Class
;
1169 SubClass
= ((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->SubClass
;
1171 // If the formset has a size value, that means someone must be using this, so create a variable
1172 // We also shall reserve the formid of 0 for this specific purpose.
1174 if ((FileFormTags
->VariableDefinitions
== NULL
) && (FormTags
->Tags
[CurrTag
].NvDataSize
> 0)) {
1175 FileFormTags
->VariableDefinitions
= AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION
));
1176 ASSERT (FileFormTags
->VariableDefinitions
!= NULL
);
1179 &FormTags
->Tags
[CurrTag
],
1180 (VOID
*) &RawFormSet
[Index
],
1181 FileFormTags
->VariableDefinitions
1184 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1188 case EFI_IFR_BANNER_OP
:
1189 if (gClassOfVfr
== EFI_FRONT_PAGE_SUBCLASS
) {
1191 CopyMem (&TempValue
, &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Alignment
, sizeof (UINT8
));
1193 // If this is the special timeout value, we will dynamically figure out where to put it
1194 // Also the least significant byte refers to the TimeOut desired.
1196 if (TempValue
== EFI_IFR_BANNER_TIMEOUT
) {
1197 CopyMem (&FrontPageTimeOutTitle
, &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Title
, sizeof (UINT16
));
1198 if (FrontPageTimeOutValue
!= (INT16
) -1) {
1199 CopyMem (&FrontPageTimeOutValue
, &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->LineNumber
, sizeof (UINT16
));
1205 &BannerData
->Banner
[((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->LineNumber
][
1206 ((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Alignment
],
1207 &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Title
,
1213 case EFI_IFR_INCONSISTENT_IF_OP
:
1215 &FormTags
->Tags
[CurrTag
].Text
,
1216 &((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Popup
,
1221 InconsistentTags
->Operand
= ((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Header
.OpCode
;
1222 CopyMem (&InconsistentTags
->Popup
, &((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Popup
, sizeof (UINT16
));
1225 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1226 // Unfortunately 0 is a valid offset value for a QuestionId
1228 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1229 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1231 InconsistentTags
->VariableNumber
= CurrentVariable
;
1234 // Test for an allocated buffer. If already allocated this is due to having called this routine
1235 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1236 // the tag structure with current values from the NV
1238 if (InconsistentTags
->Next
== NULL
) {
1239 AddNextInconsistentTag (&InconsistentTags
);
1243 InconsistentTags
= InconsistentTags
->Next
;
1246 case EFI_IFR_EQ_ID_VAL_OP
:
1247 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1249 InconsistentTags
->Operand
= ((EFI_IFR_EQ_ID_VAL
*) &RawFormSet
[Index
])->Header
.OpCode
;
1250 CopyMem (&InconsistentTags
->Value
, &((EFI_IFR_EQ_ID_VAL
*) &RawFormSet
[Index
])->Value
, sizeof (UINT16
));
1252 &InconsistentTags
->QuestionId1
,
1253 &((EFI_IFR_EQ_ID_VAL
*) &RawFormSet
[Index
])->QuestionId
,
1258 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1259 // Unfortunately 0 is a valid offset value for a QuestionId
1261 InconsistentTags
->Width
= FormTags
->Tags
[CurrTag
].StorageWidth
;
1262 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1263 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1264 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1266 InconsistentTags
->VariableNumber
= CurrentVariable
;
1269 // Test for an allocated buffer. If already allocated this is due to having called this routine
1270 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1271 // the tag structure with current values from the NV
1273 if (InconsistentTags
->Next
== NULL
) {
1274 AddNextInconsistentTag (&InconsistentTags
);
1278 InconsistentTags
= InconsistentTags
->Next
;
1281 case EFI_IFR_EQ_VAR_VAL_OP
:
1282 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1284 InconsistentTags
->Operand
= ((EFI_IFR_EQ_VAR_VAL
*) &RawFormSet
[Index
])->Header
.OpCode
;
1285 CopyMem (&InconsistentTags
->Value
, &((EFI_IFR_EQ_VAR_VAL
*) &RawFormSet
[Index
])->Value
, sizeof (UINT16
));
1287 &InconsistentTags
->QuestionId1
,
1288 &((EFI_IFR_EQ_VAR_VAL
*) &RawFormSet
[Index
])->VariableId
,
1293 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1294 // Unfortunately 0 is a valid offset value for a QuestionId
1296 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1297 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1298 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1300 InconsistentTags
->VariableNumber
= CurrentVariable
;
1303 // Test for an allocated buffer. If already allocated this is due to having called this routine
1304 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1305 // the tag structure with current values from the NV
1307 if (InconsistentTags
->Next
== NULL
) {
1308 AddNextInconsistentTag (&InconsistentTags
);
1312 InconsistentTags
= InconsistentTags
->Next
;
1315 case EFI_IFR_EQ_ID_ID_OP
:
1316 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1318 InconsistentTags
->Operand
= ((EFI_IFR_EQ_ID_ID
*) &RawFormSet
[Index
])->Header
.OpCode
;
1320 &InconsistentTags
->QuestionId1
,
1321 &((EFI_IFR_EQ_ID_ID
*) &RawFormSet
[Index
])->QuestionId1
,
1325 &InconsistentTags
->QuestionId2
,
1326 &((EFI_IFR_EQ_ID_ID
*) &RawFormSet
[Index
])->QuestionId2
,
1330 InconsistentTags
->Width
= FormTags
->Tags
[CurrTag
].StorageWidth
;
1331 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1332 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1334 InconsistentTags
->VariableNumber
= CurrentVariable
;
1335 InconsistentTags
->VariableNumber2
= CurrentVariable2
;
1338 // Test for an allocated buffer. If already allocated this is due to having called this routine
1339 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1340 // the tag structure with current values from the NV
1342 if (InconsistentTags
->Next
== NULL
) {
1343 AddNextInconsistentTag (&InconsistentTags
);
1347 InconsistentTags
= InconsistentTags
->Next
;
1350 case EFI_IFR_AND_OP
:
1352 case EFI_IFR_NOT_OP
:
1355 case EFI_IFR_TRUE_OP
:
1356 case EFI_IFR_FALSE_OP
:
1357 InconsistentTags
->Operand
= ((EFI_IFR_NOT
*) &RawFormSet
[Index
])->Header
.OpCode
;
1360 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1361 // Unfortunately 0 is a valid offset value for a QuestionId
1365 // Reserve INVALID_OFFSET_VALUE - 1 for TRUE or FALSE because they are inconsistency tags also, but
1366 // have no coresponding id. The examination of id is needed by evaluating boolean expression.
1368 if (RawFormSet
[Index
] == EFI_IFR_TRUE_OP
||
1369 RawFormSet
[Index
] == EFI_IFR_FALSE_OP
) {
1370 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
- 1;
1372 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1374 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1375 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1376 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1379 // Test for an allocated buffer. If already allocated this is due to having called this routine
1380 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1381 // the tag structure with current values from the NV
1383 if (InconsistentTags
->Next
== NULL
) {
1384 AddNextInconsistentTag (&InconsistentTags
);
1388 InconsistentTags
= InconsistentTags
->Next
;
1391 case EFI_IFR_EQ_ID_LIST_OP
:
1392 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1394 InconsistentTags
->Operand
= ((EFI_IFR_EQ_ID_LIST
*) &RawFormSet
[Index
])->Header
.OpCode
;
1396 &InconsistentTags
->QuestionId1
,
1397 &((EFI_IFR_EQ_ID_LIST
*) &RawFormSet
[Index
])->QuestionId
,
1401 &InconsistentTags
->ListLength
,
1402 &((EFI_IFR_EQ_ID_LIST
*) &RawFormSet
[Index
])->ListLength
,
1405 InconsistentTags
->ValueList
= FormTags
->Tags
[CurrTag
].IntList
;
1408 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1409 // Unfortunately 0 is a valid offset value for a QuestionId
1411 InconsistentTags
->Width
= FormTags
->Tags
[CurrTag
].StorageWidth
;
1412 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1413 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1414 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1417 // Test for an allocated buffer. If already allocated this is due to having called this routine
1418 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1419 // the tag structure with current values from the NV
1421 if (InconsistentTags
->Next
== NULL
) {
1422 AddNextInconsistentTag (&InconsistentTags
);
1426 InconsistentTags
= InconsistentTags
->Next
;
1429 case EFI_IFR_END_IF_OP
:
1430 InconsistentTags
->Operand
= ((EFI_IFR_END_EXPR
*) &RawFormSet
[Index
])->Header
.OpCode
;
1433 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1434 // Unfortunately 0 is a valid offset value for a QuestionId
1436 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1437 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1440 // Test for an allocated buffer. If already allocated this is due to having called this routine
1441 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1442 // the tag structure with current values from the NV
1444 if (InconsistentTags
->Next
== NULL
) {
1445 AddNextInconsistentTag (&InconsistentTags
);
1449 InconsistentTags
= InconsistentTags
->Next
;
1452 case EFI_IFR_END_ONE_OF_OP
:
1461 // Per spec., we ignore ops that we don't know how to deal with. Skip to next tag
1463 Index
= (UINT16
) (Index
+ TagLength
);
1468 // When we eventually exit, make sure we mark the last tag with an op-code
1470 FormTags
->Tags
[CurrTag
].Operand
= RawFormSet
[Index
];
1472 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1475 // Place this as an end of the database marker
1477 InconsistentTags
->Operand
= 0xFF;
1480 // This is the Head of the linked list of pages. Each page is an array of tags
1482 FormTags
= &FileFormTags
->FormTags
;
1483 InconsistentTags
= FileFormTags
->InconsistentTags
;
1485 for (; InconsistentTags
->Operand
!= 0xFF;) {
1486 if (InconsistentTags
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1488 // Search the tags for the tag which corresponds to this ID
1490 for (CurrTag
= 0; FormTags
->Tags
[0].Operand
!= EFI_IFR_END_FORM_SET_OP
; CurrTag
++) {
1492 // If we hit the end of a form, go to the next set of Tags.
1493 // Remember - EndFormSet op-codes sit on their own page after an end form.
1495 if (FormTags
->Tags
[CurrTag
].Operand
== EFI_IFR_END_FORM_OP
) {
1497 // Reset the CurrTag value (it will be incremented, after this case statement
1498 // so set to a negative one so that we get the desired effect.) Fish can beat me later.
1501 FormTags
= FormTags
->Next
;
1505 if (FormTags
->Tags
[CurrTag
].Id
== InconsistentTags
->QuestionId1
) {
1506 FormTags
->Tags
[CurrTag
].Consistency
++;
1511 FormTags
= &FileFormTags
->FormTags
;
1513 if (InconsistentTags
->QuestionId2
!= INVALID_OFFSET_VALUE
) {
1515 // Search the tags for the tag which corresponds to this ID
1517 for (CurrTag
= 0; FormTags
->Tags
[CurrTag
].Operand
!= EFI_IFR_END_FORM_SET_OP
; CurrTag
++) {
1519 // If we hit the end of a form, go to the next set of Tags.
1520 // Remember - EndFormSet op-codes sit on their own page after an end form.
1522 if (FormTags
->Tags
[CurrTag
].Operand
== EFI_IFR_END_FORM_OP
) {
1524 // Reset the CurrTag value (it will be incremented, after this case statement
1525 // so set to a negative one so that we get the desired effect.) Fish can beat me later.
1528 FormTags
= FormTags
->Next
;
1532 if (FormTags
->Tags
[CurrTag
].Id
== InconsistentTags
->QuestionId2
) {
1533 FormTags
->Tags
[CurrTag
].Consistency
++;
1538 InconsistentTags
= InconsistentTags
->Next
;
1549 CHAR16
*HomePageString
;
1550 CHAR16
*HomeEscapeString
;
1553 // Displays the Header and Footer borders
1555 DisplayPageFrame ();
1557 HomePageString
= GetToken (STRING_TOKEN (HOME_PAGE_TITLE
), gHiiHandle
);
1558 HomeEscapeString
= GetToken (STRING_TOKEN (HOME_ESCAPE_STRING
), gHiiHandle
);
1560 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
1562 // PrintStringAt ((gScreenDimensions.RightColumn - GetStringWidth(HomePageString)/2)/2, 1, HomePageString);
1565 (gScreenDimensions
.RightColumn
+ gScreenDimensions
.LeftColumn
- GetStringWidth (HomePageString
) / 2) / 2,
1570 gScreenDimensions
.LeftColumn
+ 2,
1571 gScreenDimensions
.BottomRow
- 3,
1572 (CHAR16
*) L
"%c%c%s",
1578 gScreenDimensions
.RightColumn
- (GetStringWidth (HomeEscapeString
) / 2) - 2,
1579 gScreenDimensions
.BottomRow
- 3,
1583 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1584 gBS
->FreePool (HomeEscapeString
);
1585 gBS
->FreePool (HomePageString
);
1592 IN STRING_REF Token
,
1593 IN EFI_HII_HANDLE HiiHandle
1597 Routine Description:
1599 Get the string based on the TokenID and HII Handle.
1603 Token - The Token ID.
1604 HiiHandle - Handle of Ifr to be fetched.
1617 // Set default string size assumption at no more than 256 bytes
1619 BufferLength
= 0x100;
1621 Buffer
= AllocateZeroPool (BufferLength
);
1622 ASSERT (Buffer
!= NULL
);
1624 Status
= Hii
->GetString (Hii
, HiiHandle
, Token
, TRUE
, NULL
, &BufferLength
, Buffer
);
1626 if (EFI_ERROR (Status
)) {
1627 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1629 // Free the old pool
1631 gBS
->FreePool (Buffer
);
1634 // Allocate new pool with correct value
1636 Buffer
= AllocatePool (BufferLength
);
1637 ASSERT (Buffer
!= NULL
);
1639 Status
= Hii
->GetString (Hii
, HiiHandle
, Token
, TRUE
, NULL
, &BufferLength
, Buffer
);
1641 if (!EFI_ERROR (Status
)) {
1646 ASSERT_EFI_ERROR (Status
);
1655 IN UINTN NumberOfIfrImages
,
1656 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
1661 EFI_IFR_BINARY
*IfrBinary
;
1663 EFI_FILE_FORM_TAGS
*FileFormTags
;
1664 EFI_FORM_TAGS LocalTags
;
1666 FileFormTags
= FileFormTagsHead
;
1670 Status
= EFI_SUCCESS
;
1673 // If there are no images
1675 if (NumberOfIfrImages
== 0) {
1676 Status
= EFI_NO_MEDIA
;
1680 // IfrBinary points to the beginning of the Binary data linked-list
1682 IfrBinary
= gBinaryDataHead
;
1685 // Print the entries which were in the default language.
1687 for (Index
= 0; Index
< NumberOfIfrImages
; Index
++) {
1688 LocalTags
= FileFormTags
->FormTags
;
1691 // Populate the Menu
1693 StringPtr
= GetToken (IfrBinary
->TitleToken
, IfrBinary
->Handle
);
1696 // If the default language doesn't exist, don't add a menu option yet
1698 if (StringPtr
[0] != CHAR_NULL
) {
1700 // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
1701 // it in UiFreeMenu.
1703 UiAddMenuOption (StringPtr
, IfrBinary
->Handle
, LocalTags
.Tags
, IfrBinary
->FormBinary
, Index
);
1706 // Advance to the next HII handle
1708 IfrBinary
= IfrBinary
->Next
;
1709 FileFormTags
= FileFormTags
->NextFile
;
1718 IN UINTN NumberOfIfrImages
,
1719 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
1720 IN UINT8
*CallbackData
1724 UI_MENU_OPTION
*Selection
;
1727 // This prints the basic home page template which the user sees
1731 Status
= PopulateHomePage (NumberOfIfrImages
, FileFormTagsHead
);
1733 if (EFI_ERROR (Status
)) {
1738 Selection
= UiDisplayMenu (FALSE
, FileFormTagsHead
, (EFI_IFR_DATA_ARRAY
*) CallbackData
);
1745 InitializeBinaryStructures (
1746 IN EFI_HII_HANDLE
*Handle
,
1747 IN BOOLEAN UseDatabase
,
1748 IN EFI_IFR_PACKET
*Packet
,
1749 IN UINT8
*NvMapOverride
,
1750 IN UINTN NumberOfIfrImages
,
1751 OUT EFI_FILE_FORM_TAGS
**FileFormTagsHead
1756 EFI_IFR_BINARY
*BinaryData
;
1757 EFI_FILE_FORM_TAGS
*FileFormTags
;
1758 UINTN SizeOfNvStore
;
1759 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
1760 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
1761 EFI_VARIABLE_DEFINITION
*OverrideDefinition
;
1764 EFI_HII_VARIABLE_PACK_LIST
*NvMapListHead
;
1765 EFI_HII_VARIABLE_PACK_LIST
*NvMapListNode
;
1768 // Initialize some variables to avoid warnings
1771 *FileFormTagsHead
= NULL
;
1772 FileFormTags
= NULL
;
1773 gBinaryDataHead
= NULL
;
1774 Status
= EFI_SUCCESS
;
1775 FormCallback
= NULL
;
1779 if (NumberOfIfrImages
> 1) {
1780 NvMapOverride
= NULL
;
1783 for (HandleIndex
= 0; HandleIndex
< NumberOfIfrImages
; HandleIndex
+= 1) {
1785 // If the buffers are uninitialized, allocate them, otherwise work on the ->Next members
1787 if ((BinaryData
== NULL
) || (FileFormTags
== NULL
)) {
1789 // Allocate memory for our Binary Data
1791 BinaryData
= AllocateZeroPool (sizeof (EFI_IFR_BINARY
));
1792 ASSERT (BinaryData
);
1795 // Preserve the Head of what will be a linked-list.
1797 gBinaryDataHead
= BinaryData
;
1798 gBinaryDataHead
->Next
= NULL
;
1801 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], NULL
, BinaryData
);
1803 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], Packet
, BinaryData
);
1806 // Allocate memory for our File Form Tags
1808 FileFormTags
= AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS
));
1809 ASSERT (FileFormTags
);
1812 // Preserve the Head of what will be a linked-list.
1814 *FileFormTagsHead
= FileFormTags
;
1815 (*FileFormTagsHead
)->NextFile
= NULL
;
1819 // Allocate memory for our Binary Data linked-list
1820 // Each handle represents a Binary and we will store that data away.
1822 BinaryData
->Next
= AllocateZeroPool (sizeof (EFI_IFR_BINARY
));
1823 ASSERT (BinaryData
->Next
);
1825 BinaryData
= BinaryData
->Next
;
1826 BinaryData
->Next
= NULL
;
1829 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], NULL
, BinaryData
);
1831 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], Packet
, BinaryData
);
1834 if (EFI_ERROR (Status
)) {
1835 return EFI_DEVICE_ERROR
;
1838 // Allocate memory for our FileFormTags linked-list
1839 // Each allocation reserves handle represents a Binary and we will store that data away.
1841 FileFormTags
->NextFile
= AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS
));
1842 ASSERT (FileFormTags
->NextFile
);
1844 FileFormTags
= FileFormTags
->NextFile
;
1849 // Tag Structure Initialization
1851 Status
= InitializeTagStructures (BinaryData
, FileFormTags
);
1853 VariableDefinition
= FileFormTags
->VariableDefinitions
;
1856 // Allocate memory for our NVRAM Maps for all of our variables
1858 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
1860 // Pad the fake variable size accordingly - this value should reflect the size of information that is not accounted by
1861 // the mainstream NVRAM variable such as DATE/TIME information that the browser needs to track but is saved to an RTC
1863 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableSize
+ VariableDefinition
->VariableFakeSize
);
1866 // In the case where a file has no "real" NV data, we should pad the buffer accordingly
1868 if (VariableDefinition
->VariableSize
== 0) {
1869 if (VariableDefinition
->VariableFakeSize
!= 0) {
1870 VariableDefinition
->NvRamMap
= AllocateZeroPool (VariableDefinition
->VariableFakeSize
);
1871 ASSERT (VariableDefinition
->NvRamMap
!= NULL
);
1874 VariableDefinition
->NvRamMap
= AllocateZeroPool (VariableDefinition
->VariableSize
);
1875 ASSERT (VariableDefinition
->NvRamMap
!= NULL
);
1878 if (VariableDefinition
->VariableFakeSize
!= 0) {
1879 VariableDefinition
->FakeNvRamMap
= AllocateZeroPool (VariableDefinition
->VariableFakeSize
);
1880 ASSERT (VariableDefinition
->FakeNvRamMap
!= NULL
);
1884 Status
= gBS
->HandleProtocol (
1885 (VOID
*) (UINTN
) FileFormTags
->FormTags
.Tags
[0].CallbackHandle
,
1886 &gEfiFormCallbackProtocolGuid
,
1887 (VOID
**) &FormCallback
1891 // Since we might have multiple variables, if there is an NvMapOverride we need to use the EFI_VARIABLE_DEFINITION
1892 // information as the information that we pass back and forth. NOTE that callbacks that are initiated will only have the
1893 // NVRAM data refreshed based on the op-code that initiated the callback. In other words, we will pass to the caller a single
1894 // NVRAM map for a single variable based on the op-code that the user selected.
1896 if (NvMapOverride
!= NULL
) {
1897 VariableDefinition
= FileFormTags
->VariableDefinitions
;
1898 OverrideDefinition
= ((EFI_VARIABLE_DEFINITION
*) NvMapOverride
);
1901 // Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified
1903 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
1904 if ((!CompareMem (VariableDefinition
->VariableName
, L
"Setup", 10)) && (VariableDefinition
->Next
== NULL
)) {
1905 if (VariableDefinition
->VariableSize
!= 0) {
1906 CopyMem (VariableDefinition
->NvRamMap
, NvMapOverride
, VariableDefinition
->VariableSize
);
1908 CopyMem (VariableDefinition
->NvRamMap
, NvMapOverride
, VariableDefinition
->VariableFakeSize
);
1912 VariableDefinition
->NvRamMap
= OverrideDefinition
->NvRamMap
;
1915 // There should NEVER be a ->Next for VariableDefinition and a NULL ->Next for the OverrideDefinition
1917 ASSERT (OverrideDefinition
->Next
);
1918 OverrideDefinition
= OverrideDefinition
->Next
;
1921 VariableDefinition
= FileFormTags
->VariableDefinitions
;
1924 // Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified
1926 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
1927 SizeOfNvStore
= VariableDefinition
->VariableSize
;
1930 // Getting the NvStore and placing it into our Global Data
1932 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
1933 Status
= FormCallback
->NvRead (
1935 VariableDefinition
->VariableName
,
1936 &VariableDefinition
->Guid
,
1939 (VOID
*) VariableDefinition
->NvRamMap
1942 Status
= gRT
->GetVariable (
1943 VariableDefinition
->VariableName
,
1944 &VariableDefinition
->Guid
,
1947 (VOID
*) VariableDefinition
->NvRamMap
1951 if (EFI_ERROR (Status
)) {
1953 // If there is a variable that exists already and it is larger than what we calculated the
1954 // storage needs to be, we must assume the variable size from GetVariable is correct and not
1955 // allow the truncation of the variable. It is very possible that the user who created the IFR
1956 // we are cracking is not referring to a variable that was in a previous map, however we cannot
1957 // allow it's truncation.
1959 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1961 // If the buffer was too small, we should have the expanded size requirement in SizeOfNvStore now.
1963 VariableDefinition
->VariableSize
= (UINT16
) SizeOfNvStore
;
1966 // Free the buffer that was allocated that was too small
1968 gBS
->FreePool (VariableDefinition
->NvRamMap
);
1969 gBS
->FreePool (VariableDefinition
->FakeNvRamMap
);
1971 VariableDefinition
->NvRamMap
= AllocateZeroPool (SizeOfNvStore
);
1972 VariableDefinition
->FakeNvRamMap
= AllocateZeroPool (SizeOfNvStore
+ VariableDefinition
->VariableFakeSize
);
1973 ASSERT (VariableDefinition
->NvRamMap
);
1974 ASSERT (VariableDefinition
->FakeNvRamMap
);
1976 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
1977 Status
= FormCallback
->NvRead (
1979 VariableDefinition
->VariableName
,
1980 &VariableDefinition
->Guid
,
1983 (VOID
*) VariableDefinition
->NvRamMap
1986 Status
= gRT
->GetVariable (
1987 VariableDefinition
->VariableName
,
1988 &VariableDefinition
->Guid
,
1991 (VOID
*) VariableDefinition
->NvRamMap
1996 // if the variable was not found, we will retrieve default values
1998 if (Status
== EFI_NOT_FOUND
) {
2000 if (0 == CompareMem (VariableDefinition
->VariableName
, L
"Setup", 10)) {
2002 NvMapListHead
= NULL
;
2004 Status
= Hii
->GetDefaultImage (Hii
, Handle
[HandleIndex
], EFI_IFR_FLAG_DEFAULT
, &NvMapListHead
);
2006 if (!EFI_ERROR (Status
)) {
2007 ASSERT_EFI_ERROR (NULL
!= NvMapListHead
);
2009 NvMapListNode
= NvMapListHead
;
2011 while (NULL
!= NvMapListNode
) {
2012 if (VariableDefinition
->VariableId
== NvMapListNode
->VariablePack
->VariableId
) {
2013 NvMap
= (VOID
*) ((CHAR8
*) NvMapListNode
->VariablePack
+ sizeof (EFI_HII_VARIABLE_PACK
) + NvMapListNode
->VariablePack
->VariableNameLength
);
2014 NvMapSize
= NvMapListNode
->VariablePack
->Header
.Length
- sizeof (EFI_HII_VARIABLE_PACK
) - NvMapListNode
->VariablePack
->VariableNameLength
;
2017 NvMapListNode
= NvMapListNode
->NextVariablePack
;
2021 // Free the buffer that was allocated.
2023 gBS
->FreePool (VariableDefinition
->NvRamMap
);
2024 gBS
->FreePool (VariableDefinition
->FakeNvRamMap
);
2027 // Allocate, copy the NvRamMap.
2029 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
- VariableDefinition
->VariableSize
);
2030 VariableDefinition
->VariableSize
= (UINT16
) NvMapSize
;
2031 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ VariableDefinition
->VariableSize
);
2033 VariableDefinition
->NvRamMap
= AllocateZeroPool (VariableDefinition
->VariableSize
);
2034 VariableDefinition
->FakeNvRamMap
= AllocateZeroPool (NvMapSize
+ VariableDefinition
->VariableFakeSize
);
2036 CopyMem (VariableDefinition
->NvRamMap
, NvMap
, NvMapSize
);
2037 gBS
->FreePool (NvMapListHead
);
2041 Status
= EFI_SUCCESS
;
2047 InitializeTagStructures (BinaryData
, FileFormTags
);
2058 IN EFI_HII_PROTOCOL
*Hii
,
2059 IN EFI_HII_HANDLE HiiHandle
,
2060 IN EFI_IFR_PACKET
*Packet
,
2061 IN OUT EFI_IFR_BINARY
*BinaryData
2065 Routine Description:
2066 Fetch the Ifr binary data.
2069 Hii - Point to HII protocol.
2070 HiiHandle - Handle of Ifr to be fetched.
2071 Packet - Pointer to IFR packet.
2072 BinaryData - Buffer to copy the string into
2075 Returns the number of CHAR16 characters that were copied into the OutputString buffer.
2081 EFI_HII_PACKAGES
*PackageList
;
2084 UINT8
*RawFormBinary
;
2085 EFI_IFR_FORM_SET
*FormOp
;
2091 // Initialize the TitleToken to 0 just in case not found
2096 // Try for a 32K Buffer
2098 BufferSize
= 0x8000;
2101 // Allocate memory for our Form binary
2103 Buffer
= AllocateZeroPool (BufferSize
);
2106 if (Packet
== NULL
) {
2107 Status
= Hii
->GetForms (Hii
, HiiHandle
, 0, &BufferSize
, Buffer
);
2109 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2111 gBS
->FreePool (Buffer
);
2114 // Allocate memory for our Form binary
2116 Buffer
= AllocatePool (BufferSize
);
2119 Status
= Hii
->GetForms (Hii
, HiiHandle
, 0, &BufferSize
, Buffer
);
2123 // Copies the data to local usable buffer
2125 CopyMem (Buffer
, Packet
->IfrData
, Packet
->IfrData
->Header
.Length
);
2128 // Register the string data with HII
2130 PackageList
= PreparePackages (2, NULL
, Packet
->IfrData
, Packet
->StringData
);
2132 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
2134 gBS
->FreePool (PackageList
);
2137 if (EFI_ERROR (Status
)) {
2141 // We now have the IFR binary in our Buffer
2143 BinaryData
->IfrPackage
= Buffer
;
2144 RawFormBinary
= (UINT8
*) ((CHAR8
*) (Buffer
) + sizeof (EFI_HII_PACK_HEADER
));
2145 BinaryData
->FormBinary
= (UINT8
*) ((CHAR8
*) (Buffer
) + sizeof (EFI_HII_PACK_HEADER
));
2146 BinaryData
->Handle
= HiiHandle
;
2149 // If a packet was passed in, remove the string data when exiting.
2151 if (Packet
!= NULL
) {
2152 BinaryData
->UnRegisterOnExit
= TRUE
;
2154 BinaryData
->UnRegisterOnExit
= FALSE
;
2157 // Walk through the FormSet Opcodes looking for the FormSet opcode
2158 // If we hit EFI_IFR_END_SET_OP we know we hit the end of the FormSet.
2160 for (Index
= 0; RawFormBinary
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
2161 FormOp
= (EFI_IFR_FORM_SET
*) &RawFormBinary
[Index
];
2162 Index
= (UINT16
) (Index
+ FormOp
->Header
.Length
);
2164 if (FormOp
->Header
.OpCode
== EFI_IFR_FORM_SET_OP
) {
2165 TitleToken
= FormOp
->FormSetTitle
;
2167 // If displaying FrontPage - set the flag signifying it
2169 switch (FormOp
->SubClass
) {
2170 case EFI_FRONT_PAGE_SUBCLASS
:
2171 FrontPageHandle
= HiiHandle
;
2174 gClassOfVfr
= FormOp
->SubClass
;
2177 // Match GUID to find out the function key setting. If match fail, use the default setting.
2179 for (Index2
= 0; Index2
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index2
++) {
2180 if (CompareGuid ((EFI_GUID
*)(UINTN
)&FormOp
->Guid
, &(gFunctionKeySettingTable
[Index2
].FormSetGuid
))) {
2182 // Update the function key setting.
2184 gFunctionKeySetting
= gFunctionKeySettingTable
[Index2
].KeySetting
;
2186 // Function key prompt can not be displayed if the function key has been disabled.
2188 if ((gFunctionKeySetting
& FUNCTION_ONE
) != FUNCTION_ONE
) {
2189 gFunctionOneString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2192 if ((gFunctionKeySetting
& FUNCTION_TWO
) != FUNCTION_TWO
) {
2193 gFunctionTwoString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2196 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2197 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2200 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2201 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2208 BinaryData
->TitleToken
= TitleToken
;
2213 EFI_HANDLE PrintHandle
= NULL
;
2214 EFI_PRINT_PROTOCOL mPrintProtocol
= { UnicodeVSPrint
};
2222 return gBS
->InstallProtocolInterface (
2224 &gEfiPrintProtocolGuid
,
2225 EFI_NATIVE_INTERFACE
,