2 Entry and initialization module for the browser.
4 Copyright (c) 2006 - 2007 Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 FUNCTIION_KEY_SETTING gFunctionKeySettingTable
[] = {
38 NONE_FUNCTION_KEY_SETTING
59 NONE_FUNCTION_KEY_SETTING
80 NONE_FUNCTION_KEY_SETTING
83 // BMM File Explorer Formset.
101 NONE_FUNCTION_KEY_SETTING
107 InitializeBinaryStructures (
108 IN EFI_HII_HANDLE
*Handle
,
109 IN BOOLEAN UseDatabase
,
110 IN EFI_IFR_PACKET
*Packet
,
111 IN UINT8
*NvMapOverride
,
112 IN UINTN NumberOfIfrImages
,
113 EFI_FILE_FORM_TAGS
**FileFormTagsHead
118 InitializeTagStructures (
119 IN EFI_IFR_BINARY
*BinaryData
,
120 OUT EFI_FILE_FORM_TAGS
*FileFormTags
126 IN UINTN NumberOfIfrImages
,
127 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
128 IN UINT8
*CallbackData
134 IN EFI_HII_PROTOCOL
*Hii
,
135 IN EFI_HII_HANDLE HiiHandle
,
136 IN EFI_IFR_PACKET
*Packet
,
137 IN EFI_IFR_BINARY
*BinaryData
150 IN EFI_FORM_BROWSER_PROTOCOL
* This
,
151 IN BOOLEAN UseDatabase
,
152 IN EFI_HII_HANDLE
* Handle
,
153 IN UINTN HandleCount
,
154 IN EFI_IFR_PACKET
* Packet
,
155 IN EFI_HANDLE CallbackHandle
,
156 IN UINT8
*NvMapOverride
,
157 IN EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
158 OUT BOOLEAN
*ResetRequired OPTIONAL
164 This is the routine which an external caller uses to direct the browser
165 where to obtain it's information.
169 UseDatabase - If set to TRUE, then all information is retrieved from the HII database handle specified
170 If set to FALSE, then the passed in Packet and CallbackHandle is used and Handle is ignored
172 Handle - A pointer to an array of Handles. If HandleCount > 1 we display a list of the formsets for the handles specified
174 HandleCount - The number of Handles specified in Handle.
176 Packet - Valid only if UseDatabase is FALSE. Packet defines the pages being passed into
177 the browser. This is composed of IFR data as well as String information.
179 CallbackHandle - The handle which contains the calling driver's EFI_FORM_CALLBACK_PROTOCOL interface.
181 ScreenDimenions - This allows the browser to be called so that it occupies a portion of the physical screen instead of
182 dynamically determining the screen dimensions.
184 NvMapOverride - This buffer is used only when there is no NV variable to define the current settings and the caller
185 needs to provide to the browser the current settings for the "fake" NV variable. If used, no saving
186 of an NV variable will be possible. This parameter is also ignored if HandleCount > 1.
192 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
193 EFI_FILE_FORM_TAGS
*FileFormTagsHead
;
194 UI_MENU_OPTION
*Selection
;
195 UI_MENU_OPTION
*AltSelection
;
199 EFI_HII_HANDLE BackupHandle
;
201 ZeroMem (&gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
203 gPreviousValue
= AllocatePool (0x1000);
204 CallbackData
= AllocatePool (0x10000);
205 ASSERT (gPreviousValue
!= NULL
);
206 ASSERT (CallbackData
!= NULL
);
210 // Seed the dimensions in the global
212 gST
->ConOut
->QueryMode (
214 gST
->ConOut
->Mode
->Mode
,
215 &gScreenDimensions
.RightColumn
,
216 &gScreenDimensions
.BottomRow
219 if (ScreenDimensions
!= NULL
) {
221 // Check local dimension vs. global dimension.
223 if ((gScreenDimensions
.RightColumn
< ScreenDimensions
->RightColumn
) ||
224 (gScreenDimensions
.BottomRow
< ScreenDimensions
->BottomRow
)
226 return EFI_INVALID_PARAMETER
;
229 // Local dimension validation.
231 if ((ScreenDimensions
->RightColumn
> ScreenDimensions
->LeftColumn
) &&
232 (ScreenDimensions
->BottomRow
> ScreenDimensions
->TopRow
) &&
233 ((ScreenDimensions
->RightColumn
- ScreenDimensions
->LeftColumn
) > 2) &&
235 (ScreenDimensions
->BottomRow
- ScreenDimensions
->TopRow
) > STATUS_BAR_HEIGHT
+
236 SCROLL_ARROW_HEIGHT
*
238 FRONT_PAGE_HEADER_HEIGHT
+
243 CopyMem (&gScreenDimensions
, ScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
245 return EFI_INVALID_PARAMETER
;
250 gOptionBlockWidth
= (CHAR16
) ((gScreenDimensions
.RightColumn
- gScreenDimensions
.LeftColumn
) / 3);
251 gHelpBlockWidth
= gOptionBlockWidth
;
252 gPromptBlockWidth
= gOptionBlockWidth
;
255 // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
257 InitializeBrowserStrings ();
259 gFunctionKeySetting
= DEFAULT_FUNCTION_KEY_SETTING
;
260 gClassOfVfr
= EFI_SETUP_APPLICATION_SUBCLASS
;
261 gResetRequired
= FALSE
;
262 gExitRequired
= FALSE
;
263 gSaveRequired
= FALSE
;
264 gNvUpdateRequired
= FALSE
;
268 BackupHandle
= *Handle
;
269 gMenuRefreshHead
= NULL
;
270 ASSERT (CallbackData
);
271 ZeroMem (CallbackData
, 0x10000);
274 // We can recurse through this and might need to re-allocate this particular buffer
276 if (gPreviousValue
== NULL
) {
277 gPreviousValue
= AllocatePool (0x1000);
278 ASSERT (gPreviousValue
!= NULL
);
284 if (CallbackHandle
!= NULL
) {
286 // Retrieve the Callback protocol interface
288 Status
= gBS
->HandleProtocol (
290 &gEfiFormCallbackProtocolGuid
,
291 (VOID
**) &FormCallback
294 if (EFI_ERROR (Status
)) {
295 gBS
->FreePool (CallbackData
);
302 // Initializes all the internal state structures for all IFR images in system
304 Status
= InitializeBinaryStructures (Handle
, UseDatabase
, Packet
, NvMapOverride
, HandleCount
, &FileFormTagsHead
);
306 if (EFI_ERROR (Status
)) {
307 gBS
->FreePool (CallbackData
);
311 // Beginning of the Presentation of the Data
313 if (UseDatabase
&& (HandleCount
> 1)) {
314 Selection
= DisplayHomePage (HandleCount
, FileFormTagsHead
, CallbackData
);
317 // If passing something specific, we know there is only one Ifr
319 Selection
= AllocateZeroPool (sizeof (UI_MENU_OPTION
));
320 ASSERT (Selection
!= NULL
);
321 Selection
->IfrNumber
= 0;
322 Selection
->Handle
= Handle
[0];
328 if (UseDatabase
&& (HandleCount
> 1)) {
329 if (Selection
== NULL
) {
330 gBS
->FreePool (CallbackData
);
335 // Launch the setup browser with the user's selection information
337 AltSelection
= SetupBrowser (Selection
, Callback
, FileFormTagsHead
, CallbackData
);
340 // If the caller cares about Reset status, we can return to the caller if something happened that required a reset
342 if (ResetRequired
!= NULL
) {
343 *ResetRequired
= gResetRequired
;
346 if (Callback
&& (AltSelection
!= NULL
)) {
347 if ((FormCallback
!= NULL
) && (FormCallback
->Callback
!= NULL
)) {
348 Status
= FormCallback
->Callback (
350 AltSelection
->ThisTag
->Key
,
352 (EFI_HII_CALLBACK_PACKET
**) &Packet
357 *Handle
= BackupHandle
;
359 if (EFI_ERROR (Status
)) {
360 gBS
->FreePool (CallbackData
);
364 if (Callback
&& (AltSelection
== NULL
)) {
365 gBS
->FreePool (CallbackData
);
369 if (UseDatabase
&& (HandleCount
> 1)) {
372 if (gBinaryDataHead
->UnRegisterOnExit
) {
373 Hii
->RemovePack (Hii
, Handle
[0]);
377 ((AltSelection
->ThisTag
->SubClass
== EFI_FRONT_PAGE_SUBCLASS
) ||
378 (AltSelection
->ThisTag
->SubClass
== EFI_SINGLE_USE_SUBCLASS
))) {
380 // If this is the FrontPage, return after every selection
382 gBS
->FreePool (Selection
);
386 // Clean up the allocated data buffers
388 FreeData (FileFormTagsHead
, NULL
, NULL
);
390 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
391 gST
->ConOut
->ClearScreen (gST
->ConOut
);
393 gBS
->FreePool (CallbackData
);
397 gBS
->FreePool (Selection
);
401 // Clean up the allocated data buffers
403 FreeData (FileFormTagsHead
, NULL
, NULL
);
405 gST
->ConOut
->ClearScreen (gST
->ConOut
);
408 gBS
->FreePool (CallbackData
);
413 } while (!EFI_ERROR (Status
));
415 gBS
->FreePool (CallbackData
);
422 IN EFI_HANDLE ImageHandle
,
423 IN EFI_SYSTEM_TABLE
*SystemTable
431 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
434 EFI_SUCCESS - Setup loaded.
440 EFI_FORM_CONFIGURATION_DATA
*FormData
;
441 EFI_FORM_BROWSER_PROTOCOL
*FormBrowser
;
443 EFI_HII_PACKAGES
*PackageList
;
446 // There will be only one FormConfig in the system
447 // If there is another out there, someone is trying to install us
448 // again. Fail that scenario.
450 Status
= gBS
->LocateProtocol (
451 &gEfiFormBrowserProtocolGuid
,
453 (VOID
**) &FormBrowser
459 // If there was no error, assume there is an installation and fail to load
461 if (!EFI_ERROR (Status
)) {
462 return EFI_DEVICE_ERROR
;
465 FormData
= AllocatePool (sizeof (EFI_FORM_CONFIGURATION_DATA
));
467 if (FormData
== NULL
) {
468 return EFI_OUT_OF_RESOURCES
;
473 FormData
->Signature
= EFI_FORM_DATA_SIGNATURE
;
474 FormData
->FormConfig
.SendForm
= SendForm
;
475 FormData
->FormConfig
.CreatePopUp
= CreateDialog
;
478 // There should only be one HII image
480 Status
= gBS
->LocateProtocol (
481 &gEfiHiiProtocolGuid
,
483 (VOID
**) &FormData
->Hii
486 ASSERT_EFI_ERROR (Status
);
490 PackageList
= PreparePackages (1, &gEfiFormBrowserProtocolGuid
, SetupBrowserStrings
);
492 Status
= Hii
->NewPack (Hii
, PackageList
, &gHiiHandle
);
494 gBS
->FreePool (PackageList
);
497 // Install protocol interface
500 Status
= gBS
->InstallProtocolInterface (
502 &gEfiFormBrowserProtocolGuid
,
503 EFI_NATIVE_INTERFACE
,
504 &FormData
->FormConfig
507 ASSERT_EFI_ERROR (Status
);
509 BannerData
= AllocateZeroPool (sizeof (BANNER_DATA
));
510 ASSERT (BannerData
!= NULL
);
512 Status
= InstallPrint ();
519 IN UINT8
*RawFormSet
,
521 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
522 IN UINT16 CurrentVariable
527 Initialize question tag's members.
530 Tag - Pointer of the current EFI_TAG structure.
531 RawFormSet - Pointer of the formset raw data.
532 Index - Offset of the current opcode in the Ifr raw data.
533 FileFormTags - Pointer of current EFI_FILE_FORM_TAGS structure.
534 CurrentVariable - Current variable number.
540 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
542 Tag
->NumberOfLines
= 1;
543 Tag
->VariableNumber
= CurrentVariable
;
544 CopyMem (&Tag
->Id
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
545 CopyMem (&Tag
->StorageStart
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
546 CopyMem (&Tag
->StorageWidth
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Width
, sizeof (UINT8
));
547 CopyMem (&Tag
->Text
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Prompt
, sizeof (UINT16
));
548 CopyMem (&Tag
->Help
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Help
, sizeof (UINT16
));
550 VariableDefinition
= FileFormTags
->VariableDefinitions
;
552 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
554 // Have we found the correct variable for the request?
556 if (CurrentVariable
== VariableDefinition
->VariableId
) {
557 if (VariableDefinition
->VariableSize
< (UINTN
) (Tag
->StorageStart
+ Tag
->StorageWidth
)) {
558 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ Tag
->StorageWidth
);
561 if (VariableDefinition
->NvRamMap
!= NULL
) {
563 // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
564 // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
566 if (Tag
->StorageWidth
== (UINT16
) 1) {
567 CopyMem (&Tag
->Value
, &VariableDefinition
->NvRamMap
[Tag
->StorageStart
], sizeof (UINT16
));
570 if (Tag
->StorageWidth
== (UINT16
) 2) {
573 VariableDefinition
->NvRamMap
[Tag
->StorageStart
] +
574 (VariableDefinition
->NvRamMap
[Tag
->StorageStart
+ 1] * 0x100)
576 CopyMem (&Tag
->Value
, &Index
, sizeof (UINT16
));
580 CopyMem (&Tag
->Value
, &Index
, sizeof (UINT16
));
590 IN UINT8
*RawFormSet
,
592 IN UINT16 NumberOfLines
,
593 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
594 IN UINT16 CurrentVariable
599 Initialize numeric tag's members.
602 Tag - Pointer of the current EFI_TAG structure.
603 RawFormSet - Pointer of the formset raw data.
604 Index - Offset of the current opcode in the Ifr raw data.
605 NumberOfLines - Number of lines this opcode occupied.
606 FileFormTags - Pointer of current EFI_FILE_FORM_TAGS structure.
607 CurrentVariable - Current variable number.
613 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
615 Tag
->NumberOfLines
= NumberOfLines
;
616 Tag
->VariableNumber
= CurrentVariable
;
617 CopyMem (&Tag
->Id
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
618 CopyMem (&Tag
->StorageStart
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->QuestionId
, sizeof (UINT16
));
619 CopyMem (&Tag
->StorageWidth
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Width
, sizeof (UINT8
));
620 CopyMem (&Tag
->Text
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Prompt
, sizeof (UINT16
));
621 CopyMem (&Tag
->Help
, &((EFI_IFR_ONE_OF
*) &RawFormSet
[Index
])->Help
, sizeof (UINT16
));
622 CopyMem (&Tag
->Minimum
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Minimum
, sizeof (UINT16
));
623 CopyMem (&Tag
->Maximum
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Maximum
, sizeof (UINT16
));
624 CopyMem (&Tag
->Step
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Step
, sizeof (UINT16
));
625 CopyMem (&Tag
->Default
, &((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Default
, sizeof (UINT16
));
626 Tag
->ResetRequired
= (BOOLEAN
) (((EFI_IFR_NUMERIC
*) &RawFormSet
[Index
])->Flags
& EFI_IFR_FLAG_RESET_REQUIRED
);
628 VariableDefinition
= FileFormTags
->VariableDefinitions
;
630 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
632 // Have we found the correct variable for the request?
634 if (CurrentVariable
== VariableDefinition
->VariableId
) {
635 if (VariableDefinition
->VariableSize
<= (UINTN
) (Tag
->StorageStart
+ Tag
->StorageWidth
)) {
636 if (Tag
->StorageWidth
== 0) {
637 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ 2);
639 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ Tag
->StorageWidth
);
643 if (VariableDefinition
->NvRamMap
!= NULL
) {
645 // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
646 // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
648 if (Tag
->StorageWidth
== (UINT16
) 1) {
649 CopyMem (&Tag
->Value
, &VariableDefinition
->NvRamMap
[Tag
->StorageStart
], sizeof (UINT16
));
652 if (Tag
->StorageWidth
== (UINT16
) 2) {
655 VariableDefinition
->NvRamMap
[Tag
->StorageStart
] +
656 (VariableDefinition
->NvRamMap
[Tag
->StorageStart
+ 1] * 0x100)
658 CopyMem (&Tag
->Value
, &Index
, sizeof (UINT16
));
661 CopyMem (&Tag
->Value
, &Tag
->Default
, sizeof (UINT16
));
670 IN UINT8
*RawFormSet
,
671 IN OUT UINT16
*NumberOfTags
677 // Assume on entry we are pointing to an OpCode - reasonably this should
678 // be a FormOp since the purpose is to count the tags in a particular Form.
680 for (Index
= 0; RawFormSet
[Index
] != EFI_IFR_END_FORM_OP
;) {
682 // If we encounter the end of a form set, bail out
684 if (RawFormSet
[Index
] == EFI_IFR_END_FORM_SET_OP
) {
688 // We treat date/time internally as three op-codes
690 if (RawFormSet
[Index
] == EFI_IFR_DATE_OP
|| RawFormSet
[Index
] == EFI_IFR_TIME_OP
) {
691 *NumberOfTags
= (UINT16
) (*NumberOfTags
+ 3);
694 // Assume that we could have no more tags than op-codes
699 Index
= (UINT16
) (Index
+ RawFormSet
[Index
+ 1]);
702 // Increase the tag count by one so it is inclusive of the end_form_op
709 AddNextInconsistentTag (
710 IN OUT EFI_INCONSISTENCY_DATA
**InconsistentTagsPtr
715 Initialize the next inconsistent tag data and add it to the inconsistent tag list.
718 InconsistentTagsPtr - Pointer of the inconsistent tag's pointer.
725 EFI_INCONSISTENCY_DATA
*PreviousInconsistentTags
;
726 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
728 InconsistentTags
= *InconsistentTagsPtr
;
730 // We just hit the end of an inconsistent expression. Let's allocate the ->Next structure
732 InconsistentTags
->Next
= AllocatePool (sizeof (EFI_INCONSISTENCY_DATA
));
733 ASSERT (InconsistentTags
->Next
!= NULL
);
736 // Preserve current Tag entry
738 PreviousInconsistentTags
= InconsistentTags
;
740 InconsistentTags
= InconsistentTags
->Next
;
743 // This will zero on the entry including the ->Next so I don't have to do it
745 ZeroMem (InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
748 // Point our Previous field to the previous entry
750 InconsistentTags
->Previous
= PreviousInconsistentTags
;
752 *InconsistentTagsPtr
= InconsistentTags
;
759 InitializeTagStructures (
760 IN EFI_IFR_BINARY
*BinaryData
,
761 OUT EFI_FILE_FORM_TAGS
*FileFormTags
767 UINT16 QuestionIndex
;
771 EFI_FORM_TAGS
*FormTags
;
772 EFI_FORM_TAGS
*SavedFormTags
;
773 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
774 EFI_VARIABLE_DEFINITION
*VariableDefinitions
;
779 UINT16 CurrentVariable
;
780 UINT16 CurrentVariable2
;
783 // Initialize some Index variable and Status
789 CurrentVariable2
= 0;
792 Status
= EFI_SUCCESS
;
793 FormTags
= &FileFormTags
->FormTags
;
794 FormTags
->Next
= NULL
;
795 if (FileFormTags
->InconsistentTags
== NULL
) {
796 InconsistentTags
= NULL
;
798 InconsistentTags
= FileFormTags
->InconsistentTags
;
801 if (FileFormTags
->VariableDefinitions
== NULL
) {
802 VariableDefinitions
= NULL
;
804 VariableDefinitions
= FileFormTags
->VariableDefinitions
;
807 // RawFormSet now points to the beginning of the forms portion of
808 // the specific IFR Binary.
810 RawFormSet
= (UINT8
*) BinaryData
->FormBinary
;
813 // Determine the number of tags for the first form
815 GetTagCount (&RawFormSet
[0], &NumberOfTags
);
817 SavedFormTags
= FormTags
;
819 if (FormTags
->Tags
!= NULL
) {
822 // Advance FormTags to the last entry
824 for (; FormTags
->Next
!= NULL
; FormTags
= FormTags
->Next
)
828 // Walk through each of the tags and free the IntList allocation
830 for (Index
= 0; Index
< NumberOfTags
; Index
++) {
831 if (FormTags
->Tags
[Index
].IntList
!= NULL
) {
832 gBS
->FreePool (FormTags
->Tags
[Index
].IntList
);
836 gBS
->FreePool (FormTags
->Tags
);
837 gBS
->FreePool (FormTags
->Next
);
838 FormTags
->Next
= NULL
;
839 FormTags
->Tags
= NULL
;
841 FormTags
= SavedFormTags
;
843 } while (FormTags
->Next
!= NULL
);
849 // Test for an allocated buffer. If already allocated this is due to having called this routine
850 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
851 // the tag structure with current values from the NV
853 if (FormTags
->Tags
== NULL
) {
855 // Allocate memory for our tags on the first form
857 FormTags
->Tags
= AllocateZeroPool (NumberOfTags
* sizeof (EFI_TAG
));
858 ASSERT (FormTags
->Tags
);
861 // Test for an allocated buffer. If already allocated this is due to having called this routine
862 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
863 // the tag structure with current values from the NV
865 if (InconsistentTags
== NULL
) {
867 // We just hit the end of an inconsistent expression. Let's allocate the ->Next structure
869 InconsistentTags
= AllocateZeroPool (sizeof (EFI_INCONSISTENCY_DATA
));
870 ASSERT (InconsistentTags
!= NULL
);
872 FileFormTags
->InconsistentTags
= InconsistentTags
;
875 ZeroMem (FormTags
->Tags
, NumberOfTags
* sizeof (EFI_TAG
));
877 for (CurrTag
= 0; RawFormSet
[Index
] != EFI_IFR_END_FORM_SET_OP
; CurrTag
++) {
879 // Operand = IFR OpCode
881 FormTags
->Tags
[CurrTag
].Operand
= RawFormSet
[Index
];
884 // Assume for now 0 lines occupied by this OpCode
886 FormTags
->Tags
[CurrTag
].NumberOfLines
= 0;
888 FormTags
->Tags
[CurrTag
].Class
= Class
;
889 FormTags
->Tags
[CurrTag
].SubClass
= SubClass
;
892 // Determine the length of the Tag so we can later skip to the next tag in the form
894 TagLength
= RawFormSet
[Index
+ 1];
898 // Operate on the Found OpCode
900 switch (RawFormSet
[Index
]) {
902 case EFI_IFR_FORM_OP
:
904 // If there was no variable op-code defined, create a dummy entry for one
906 if (FileFormTags
->VariableDefinitions
== NULL
) {
907 FileFormTags
->VariableDefinitions
= AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION
));
908 ASSERT (FileFormTags
->VariableDefinitions
!= NULL
);
911 &FormTags
->Tags
[CurrTag
],
912 (VOID
*) &RawFormSet
[Index
],
913 FileFormTags
->VariableDefinitions
916 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
920 case EFI_IFR_SUBTITLE_OP
:
921 case EFI_IFR_TEXT_OP
:
923 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
926 case EFI_IFR_VARSTORE_OP
:
927 if (FileFormTags
->VariableDefinitions
== NULL
) {
928 VariableDefinitions
= AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION
));
929 ASSERT (VariableDefinitions
!= NULL
);
930 FileFormTags
->VariableDefinitions
= VariableDefinitions
;
935 &FormTags
->Tags
[CurrTag
],
936 (VOID
*) &RawFormSet
[Index
],
937 FileFormTags
->VariableDefinitions
941 case EFI_IFR_VARSTORE_SELECT_OP
:
942 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
943 CopyMem (&CurrentVariable
, &((EFI_IFR_VARSTORE_SELECT
*) &RawFormSet
[Index
])->VarId
, sizeof (UINT16
));
944 CurrentVariable2
= CurrentVariable
;
947 case EFI_IFR_VARSTORE_SELECT_PAIR_OP
:
948 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
949 CopyMem(&CurrentVariable
, &((EFI_IFR_VARSTORE_SELECT_PAIR
*)&RawFormSet
[Index
])->VarId
, sizeof (UINT16
));
952 &((EFI_IFR_VARSTORE_SELECT_PAIR
*) &RawFormSet
[Index
])->SecondaryVarId
,
957 case EFI_IFR_END_FORM_OP
:
959 // Test for an allocated buffer. If already allocated this is due to having called this routine
960 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
961 // the tag structure with current values from the NV
963 if (FormTags
->Next
== NULL
) {
965 // We just hit the end of a form. Let's allocate the ->Next structure
967 FormTags
->Next
= AllocatePool (sizeof (EFI_FORM_TAGS
));
968 ASSERT (FormTags
->Next
);
971 FormTags
= FormTags
->Next
;
972 ZeroMem (FormTags
, sizeof (EFI_FORM_TAGS
));
975 // Reset the tag count to one
980 // Reset the CurrTag value (it will be incremented, after this case statement
981 // so set to a negative one so that we get the desired effect.) Fish can beat me later.
986 // Determine the number of tags after this form. If this is the last
987 // form, then we will count the endformset and preserve that information
988 // in the tag structure.
990 GetTagCount (&RawFormSet
[Index
+ TagLength
], &NumberOfTags
);
993 // Allocate memory for our tags
995 FormTags
->Tags
= AllocateZeroPool (NumberOfTags
* sizeof (EFI_TAG
));
996 ASSERT (FormTags
->Tags
);
1000 // Two types of tags constitute the One Of question: a one-of header and
1001 // several one-of options.
1003 case EFI_IFR_ONE_OF_OP
:
1004 case EFI_IFR_ORDERED_LIST_OP
:
1005 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, FileFormTags
, CurrentVariable
);
1008 // Store away the CurrTag since what follows will be the answer that we
1009 // need to place into the appropriate location in the tag array
1012 // record for setting default later
1014 QuestionIndex
= (UINT16
) CurrTag
;
1017 case EFI_IFR_ONE_OF_OPTION_OP
:
1018 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1019 FormTags
->Tags
[QuestionIndex
].Flags
= ((EFI_IFR_ONE_OF_OPTION
*) &RawFormSet
[Index
])->Flags
;
1021 &FormTags
->Tags
[QuestionIndex
].Key
,
1022 &((EFI_IFR_ONE_OF_OPTION
*) &RawFormSet
[Index
])->Key
,
1025 FormTags
->Tags
[QuestionIndex
].ResetRequired
= (BOOLEAN
) (FormTags
->Tags
[QuestionIndex
].Flags
& EFI_IFR_FLAG_RESET_REQUIRED
);
1028 case EFI_IFR_CHECKBOX_OP
:
1029 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, FileFormTags
, CurrentVariable
);
1030 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1033 case EFI_IFR_NUMERIC_OP
:
1034 GetNumericHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, (UINT16
) 1, FileFormTags
, CurrentVariable
);
1035 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1038 case EFI_IFR_DATE_OP
:
1040 // Date elements come in as a Year, Month, Day. We need to process them as a country-based
1041 // Order. It is much easier to do it here than anywhere else.
1043 // For US standards - we want Month/Day/Year, thus we advance "Index" +1, +2, +0 while CurrTag is +0, +1, +2
1046 &FormTags
->Tags
[CurrTag
],
1048 (UINT16
) (Index
+ TagLength
),
1055 // The current language selected + the Date operand
1057 FormTags
->Tags
[CurrTag
+ 1].Operand
= RawFormSet
[Index
];
1059 &FormTags
->Tags
[CurrTag
+ 1],
1061 (UINT16
) (Index
+ TagLength
+ RawFormSet
[Index
+ TagLength
+ 1]),
1068 // The current language selected + the Date operand
1070 FormTags
->Tags
[CurrTag
+ 2].Operand
= RawFormSet
[Index
];
1071 GetNumericHeader (&FormTags
->Tags
[CurrTag
+ 2], RawFormSet
, Index
, (UINT16
) 1, FileFormTags
, CurrentVariable
);
1073 CurrTag
= (INT16
) (CurrTag
+ 2);
1075 Index
= (UINT16
) (Index
+ TagLength
);
1079 TagLength
= RawFormSet
[Index
+ 1];
1080 Index
= (UINT16
) (Index
+ TagLength
);
1084 TagLength
= RawFormSet
[Index
+ 1];
1087 case EFI_IFR_TIME_OP
:
1088 GetNumericHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, (UINT16
) 0, FileFormTags
, CurrentVariable
);
1092 // Override the GetQuestionHeader information - date/time are treated very differently
1094 FormTags
->Tags
[CurrTag
].NumberOfLines
= 1;
1098 // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines
1099 // associated with them, and the third has 1 line to allow to space beyond the choice.
1105 case EFI_IFR_PASSWORD_OP
:
1106 case EFI_IFR_STRING_OP
:
1107 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], RawFormSet
, Index
, FileFormTags
, CurrentVariable
);
1108 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1111 case EFI_IFR_SUPPRESS_IF_OP
:
1112 case EFI_IFR_GRAYOUT_IF_OP
:
1113 InconsistentTags
->Operand
= ((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Header
.OpCode
;
1117 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1118 // Unfortunately 0 is a valid offset value for a QuestionId
1120 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1121 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1124 // Test for an allocated buffer. If already allocated this is due to having called this routine
1125 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1126 // the tag structure with current values from the NV
1128 if (InconsistentTags
->Next
== NULL
) {
1129 AddNextInconsistentTag (&InconsistentTags
);
1133 InconsistentTags
= InconsistentTags
->Next
;
1136 case EFI_IFR_FORM_SET_OP
:
1138 &FormTags
->Tags
[CurrTag
].GuidValue
,
1139 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->Guid
,
1143 &FormTags
->Tags
[CurrTag
].CallbackHandle
,
1144 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->CallbackHandle
,
1145 sizeof (EFI_PHYSICAL_ADDRESS
)
1147 CopyMem (&FormTags
->Tags
[CurrTag
].Class
, &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->Class
, sizeof (UINT8
));
1149 &FormTags
->Tags
[CurrTag
].SubClass
,
1150 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->SubClass
,
1154 &FormTags
->Tags
[CurrTag
].NvDataSize
,
1155 &((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->NvDataSize
,
1158 Class
= ((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->Class
;
1159 SubClass
= ((EFI_IFR_FORM_SET
*) &RawFormSet
[Index
])->SubClass
;
1161 // If the formset has a size value, that means someone must be using this, so create a variable
1162 // We also shall reserve the formid of 0 for this specific purpose.
1164 if ((FileFormTags
->VariableDefinitions
== NULL
) && (FormTags
->Tags
[CurrTag
].NvDataSize
> 0)) {
1165 FileFormTags
->VariableDefinitions
= AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION
));
1166 ASSERT (FileFormTags
->VariableDefinitions
!= NULL
);
1169 &FormTags
->Tags
[CurrTag
],
1170 (VOID
*) &RawFormSet
[Index
],
1171 FileFormTags
->VariableDefinitions
1174 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1178 case EFI_IFR_BANNER_OP
:
1179 if (gClassOfVfr
== EFI_FRONT_PAGE_SUBCLASS
) {
1181 CopyMem (&TempValue
, &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Alignment
, sizeof (UINT8
));
1183 // If this is the special timeout value, we will dynamically figure out where to put it
1184 // Also the least significant byte refers to the TimeOut desired.
1186 if (TempValue
== EFI_IFR_BANNER_TIMEOUT
) {
1187 CopyMem (&FrontPageTimeOutTitle
, &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Title
, sizeof (UINT16
));
1188 if (FrontPageTimeOutValue
!= (INT16
) -1) {
1189 CopyMem (&FrontPageTimeOutValue
, &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->LineNumber
, sizeof (UINT16
));
1195 &BannerData
->Banner
[((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->LineNumber
][
1196 ((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Alignment
],
1197 &((EFI_IFR_BANNER
*) &RawFormSet
[Index
])->Title
,
1203 case EFI_IFR_INCONSISTENT_IF_OP
:
1205 &FormTags
->Tags
[CurrTag
].Text
,
1206 &((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Popup
,
1211 InconsistentTags
->Operand
= ((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Header
.OpCode
;
1212 CopyMem (&InconsistentTags
->Popup
, &((EFI_IFR_INCONSISTENT
*) &RawFormSet
[Index
])->Popup
, sizeof (UINT16
));
1215 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1216 // Unfortunately 0 is a valid offset value for a QuestionId
1218 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1219 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1221 InconsistentTags
->VariableNumber
= CurrentVariable
;
1224 // Test for an allocated buffer. If already allocated this is due to having called this routine
1225 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1226 // the tag structure with current values from the NV
1228 if (InconsistentTags
->Next
== NULL
) {
1229 AddNextInconsistentTag (&InconsistentTags
);
1233 InconsistentTags
= InconsistentTags
->Next
;
1236 case EFI_IFR_EQ_ID_VAL_OP
:
1237 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1239 InconsistentTags
->Operand
= ((EFI_IFR_EQ_ID_VAL
*) &RawFormSet
[Index
])->Header
.OpCode
;
1240 CopyMem (&InconsistentTags
->Value
, &((EFI_IFR_EQ_ID_VAL
*) &RawFormSet
[Index
])->Value
, sizeof (UINT16
));
1242 &InconsistentTags
->QuestionId1
,
1243 &((EFI_IFR_EQ_ID_VAL
*) &RawFormSet
[Index
])->QuestionId
,
1248 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1249 // Unfortunately 0 is a valid offset value for a QuestionId
1251 InconsistentTags
->Width
= FormTags
->Tags
[CurrTag
].StorageWidth
;
1252 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1253 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1254 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1256 InconsistentTags
->VariableNumber
= CurrentVariable
;
1259 // Test for an allocated buffer. If already allocated this is due to having called this routine
1260 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1261 // the tag structure with current values from the NV
1263 if (InconsistentTags
->Next
== NULL
) {
1264 AddNextInconsistentTag (&InconsistentTags
);
1268 InconsistentTags
= InconsistentTags
->Next
;
1271 case EFI_IFR_EQ_VAR_VAL_OP
:
1272 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1274 InconsistentTags
->Operand
= ((EFI_IFR_EQ_VAR_VAL
*) &RawFormSet
[Index
])->Header
.OpCode
;
1275 CopyMem (&InconsistentTags
->Value
, &((EFI_IFR_EQ_VAR_VAL
*) &RawFormSet
[Index
])->Value
, sizeof (UINT16
));
1277 &InconsistentTags
->QuestionId1
,
1278 &((EFI_IFR_EQ_VAR_VAL
*) &RawFormSet
[Index
])->VariableId
,
1283 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1284 // Unfortunately 0 is a valid offset value for a QuestionId
1286 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1287 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1288 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1290 InconsistentTags
->VariableNumber
= CurrentVariable
;
1293 // Test for an allocated buffer. If already allocated this is due to having called this routine
1294 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1295 // the tag structure with current values from the NV
1297 if (InconsistentTags
->Next
== NULL
) {
1298 AddNextInconsistentTag (&InconsistentTags
);
1302 InconsistentTags
= InconsistentTags
->Next
;
1305 case EFI_IFR_EQ_ID_ID_OP
:
1306 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1308 InconsistentTags
->Operand
= ((EFI_IFR_EQ_ID_ID
*) &RawFormSet
[Index
])->Header
.OpCode
;
1310 &InconsistentTags
->QuestionId1
,
1311 &((EFI_IFR_EQ_ID_ID
*) &RawFormSet
[Index
])->QuestionId1
,
1315 &InconsistentTags
->QuestionId2
,
1316 &((EFI_IFR_EQ_ID_ID
*) &RawFormSet
[Index
])->QuestionId2
,
1320 InconsistentTags
->Width
= FormTags
->Tags
[CurrTag
].StorageWidth
;
1321 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1322 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1324 InconsistentTags
->VariableNumber
= CurrentVariable
;
1325 InconsistentTags
->VariableNumber2
= CurrentVariable2
;
1328 // Test for an allocated buffer. If already allocated this is due to having called this routine
1329 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1330 // the tag structure with current values from the NV
1332 if (InconsistentTags
->Next
== NULL
) {
1333 AddNextInconsistentTag (&InconsistentTags
);
1337 InconsistentTags
= InconsistentTags
->Next
;
1340 case EFI_IFR_AND_OP
:
1342 case EFI_IFR_NOT_OP
:
1345 case EFI_IFR_TRUE_OP
:
1346 case EFI_IFR_FALSE_OP
:
1347 InconsistentTags
->Operand
= ((EFI_IFR_NOT
*) &RawFormSet
[Index
])->Header
.OpCode
;
1350 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1351 // Unfortunately 0 is a valid offset value for a QuestionId
1355 // Reserve INVALID_OFFSET_VALUE - 1 for TRUE or FALSE because they are inconsistency tags also, but
1356 // have no coresponding id. The examination of id is needed by evaluating boolean expression.
1358 if (RawFormSet
[Index
] == EFI_IFR_TRUE_OP
||
1359 RawFormSet
[Index
] == EFI_IFR_FALSE_OP
) {
1360 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
- 1;
1362 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1364 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1365 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1366 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1369 // Test for an allocated buffer. If already allocated this is due to having called this routine
1370 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1371 // the tag structure with current values from the NV
1373 if (InconsistentTags
->Next
== NULL
) {
1374 AddNextInconsistentTag (&InconsistentTags
);
1378 InconsistentTags
= InconsistentTags
->Next
;
1381 case EFI_IFR_EQ_ID_LIST_OP
:
1382 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1384 InconsistentTags
->Operand
= ((EFI_IFR_EQ_ID_LIST
*) &RawFormSet
[Index
])->Header
.OpCode
;
1386 &InconsistentTags
->QuestionId1
,
1387 &((EFI_IFR_EQ_ID_LIST
*) &RawFormSet
[Index
])->QuestionId
,
1391 &InconsistentTags
->ListLength
,
1392 &((EFI_IFR_EQ_ID_LIST
*) &RawFormSet
[Index
])->ListLength
,
1395 InconsistentTags
->ValueList
= FormTags
->Tags
[CurrTag
].IntList
;
1398 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1399 // Unfortunately 0 is a valid offset value for a QuestionId
1401 InconsistentTags
->Width
= FormTags
->Tags
[CurrTag
].StorageWidth
;
1402 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1403 InconsistentTags
->ConsistencyId
= gConsistencyId
;
1404 FormTags
->Tags
[CurrTag
].ConsistencyId
= gConsistencyId
;
1407 // Test for an allocated buffer. If already allocated this is due to having called this routine
1408 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1409 // the tag structure with current values from the NV
1411 if (InconsistentTags
->Next
== NULL
) {
1412 AddNextInconsistentTag (&InconsistentTags
);
1416 InconsistentTags
= InconsistentTags
->Next
;
1419 case EFI_IFR_END_IF_OP
:
1420 InconsistentTags
->Operand
= ((EFI_IFR_END_EXPR
*) &RawFormSet
[Index
])->Header
.OpCode
;
1423 // Since this op-code doesn't use the next field(s), initialize them with something invalid.
1424 // Unfortunately 0 is a valid offset value for a QuestionId
1426 InconsistentTags
->QuestionId1
= INVALID_OFFSET_VALUE
;
1427 InconsistentTags
->QuestionId2
= INVALID_OFFSET_VALUE
;
1430 // Test for an allocated buffer. If already allocated this is due to having called this routine
1431 // once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
1432 // the tag structure with current values from the NV
1434 if (InconsistentTags
->Next
== NULL
) {
1435 AddNextInconsistentTag (&InconsistentTags
);
1439 InconsistentTags
= InconsistentTags
->Next
;
1442 case EFI_IFR_END_ONE_OF_OP
:
1451 // Per spec., we ignore ops that we don't know how to deal with. Skip to next tag
1453 Index
= (UINT16
) (Index
+ TagLength
);
1458 // When we eventually exit, make sure we mark the last tag with an op-code
1460 FormTags
->Tags
[CurrTag
].Operand
= RawFormSet
[Index
];
1462 IfrToFormTag (RawFormSet
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &RawFormSet
[Index
], NULL
);
1465 // Place this as an end of the database marker
1467 InconsistentTags
->Operand
= 0xFF;
1470 // This is the Head of the linked list of pages. Each page is an array of tags
1472 FormTags
= &FileFormTags
->FormTags
;
1473 InconsistentTags
= FileFormTags
->InconsistentTags
;
1475 for (; InconsistentTags
->Operand
!= 0xFF;) {
1476 if (InconsistentTags
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1478 // Search the tags for the tag which corresponds to this ID
1480 for (CurrTag
= 0; FormTags
->Tags
[0].Operand
!= EFI_IFR_END_FORM_SET_OP
; CurrTag
++) {
1482 // If we hit the end of a form, go to the next set of Tags.
1483 // Remember - EndFormSet op-codes sit on their own page after an end form.
1485 if (FormTags
->Tags
[CurrTag
].Operand
== EFI_IFR_END_FORM_OP
) {
1487 // Reset the CurrTag value (it will be incremented, after this case statement
1488 // so set to a negative one so that we get the desired effect.) Fish can beat me later.
1491 FormTags
= FormTags
->Next
;
1495 if (FormTags
->Tags
[CurrTag
].Id
== InconsistentTags
->QuestionId1
) {
1496 FormTags
->Tags
[CurrTag
].Consistency
++;
1501 FormTags
= &FileFormTags
->FormTags
;
1503 if (InconsistentTags
->QuestionId2
!= INVALID_OFFSET_VALUE
) {
1505 // Search the tags for the tag which corresponds to this ID
1507 for (CurrTag
= 0; FormTags
->Tags
[CurrTag
].Operand
!= EFI_IFR_END_FORM_SET_OP
; CurrTag
++) {
1509 // If we hit the end of a form, go to the next set of Tags.
1510 // Remember - EndFormSet op-codes sit on their own page after an end form.
1512 if (FormTags
->Tags
[CurrTag
].Operand
== EFI_IFR_END_FORM_OP
) {
1514 // Reset the CurrTag value (it will be incremented, after this case statement
1515 // so set to a negative one so that we get the desired effect.) Fish can beat me later.
1518 FormTags
= FormTags
->Next
;
1522 if (FormTags
->Tags
[CurrTag
].Id
== InconsistentTags
->QuestionId2
) {
1523 FormTags
->Tags
[CurrTag
].Consistency
++;
1528 InconsistentTags
= InconsistentTags
->Next
;
1539 CHAR16
*HomePageString
;
1540 CHAR16
*HomeEscapeString
;
1543 // Displays the Header and Footer borders
1545 DisplayPageFrame ();
1547 HomePageString
= GetToken (STRING_TOKEN (HOME_PAGE_TITLE
), gHiiHandle
);
1548 HomeEscapeString
= GetToken (STRING_TOKEN (HOME_ESCAPE_STRING
), gHiiHandle
);
1550 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_YELLOW
| EFI_BRIGHT
);
1552 // PrintStringAt ((gScreenDimensions.RightColumn - GetStringWidth(HomePageString)/2)/2, 1, HomePageString);
1555 (gScreenDimensions
.RightColumn
+ gScreenDimensions
.LeftColumn
- GetStringWidth (HomePageString
) / 2) / 2,
1560 gScreenDimensions
.LeftColumn
+ 2,
1561 gScreenDimensions
.BottomRow
- 3,
1562 (CHAR16
*) L
"%c%c%s",
1568 gScreenDimensions
.RightColumn
- (GetStringWidth (HomeEscapeString
) / 2) - 2,
1569 gScreenDimensions
.BottomRow
- 3,
1573 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
1574 gBS
->FreePool (HomeEscapeString
);
1575 gBS
->FreePool (HomePageString
);
1582 IN STRING_REF Token
,
1583 IN EFI_HII_HANDLE HiiHandle
1587 Routine Description:
1589 Get the string based on the TokenID and HII Handle.
1593 Token - The Token ID.
1594 HiiHandle - Handle of Ifr to be fetched.
1607 // Set default string size assumption at no more than 256 bytes
1609 BufferLength
= 0x100;
1611 Buffer
= AllocateZeroPool (BufferLength
);
1612 ASSERT (Buffer
!= NULL
);
1614 Status
= Hii
->GetString (Hii
, HiiHandle
, Token
, TRUE
, NULL
, &BufferLength
, Buffer
);
1616 if (EFI_ERROR (Status
)) {
1617 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1619 // Free the old pool
1621 gBS
->FreePool (Buffer
);
1624 // Allocate new pool with correct value
1626 Buffer
= AllocatePool (BufferLength
);
1627 ASSERT (Buffer
!= NULL
);
1629 Status
= Hii
->GetString (Hii
, HiiHandle
, Token
, TRUE
, NULL
, &BufferLength
, Buffer
);
1631 if (!EFI_ERROR (Status
)) {
1636 ASSERT_EFI_ERROR (Status
);
1645 IN UINTN NumberOfIfrImages
,
1646 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
1651 EFI_IFR_BINARY
*IfrBinary
;
1653 EFI_FILE_FORM_TAGS
*FileFormTags
;
1654 EFI_FORM_TAGS LocalTags
;
1656 FileFormTags
= FileFormTagsHead
;
1660 Status
= EFI_SUCCESS
;
1663 // If there are no images
1665 if (NumberOfIfrImages
== 0) {
1666 Status
= EFI_NO_MEDIA
;
1670 // IfrBinary points to the beginning of the Binary data linked-list
1672 IfrBinary
= gBinaryDataHead
;
1675 // Print the entries which were in the default language.
1677 for (Index
= 0; Index
< NumberOfIfrImages
; Index
++) {
1678 LocalTags
= FileFormTags
->FormTags
;
1681 // Populate the Menu
1683 StringPtr
= GetToken (IfrBinary
->TitleToken
, IfrBinary
->Handle
);
1686 // If the default language doesn't exist, don't add a menu option yet
1688 if (StringPtr
[0] != CHAR_NULL
) {
1690 // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
1691 // it in UiFreeMenu.
1693 UiAddMenuOption (StringPtr
, IfrBinary
->Handle
, LocalTags
.Tags
, IfrBinary
->FormBinary
, Index
);
1696 // Advance to the next HII handle
1698 IfrBinary
= IfrBinary
->Next
;
1699 FileFormTags
= FileFormTags
->NextFile
;
1708 IN UINTN NumberOfIfrImages
,
1709 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
1710 IN UINT8
*CallbackData
1714 UI_MENU_OPTION
*Selection
;
1717 // This prints the basic home page template which the user sees
1721 Status
= PopulateHomePage (NumberOfIfrImages
, FileFormTagsHead
);
1723 if (EFI_ERROR (Status
)) {
1728 Selection
= UiDisplayMenu (FALSE
, FileFormTagsHead
, (EFI_IFR_DATA_ARRAY
*) CallbackData
);
1735 InitializeBinaryStructures (
1736 IN EFI_HII_HANDLE
*Handle
,
1737 IN BOOLEAN UseDatabase
,
1738 IN EFI_IFR_PACKET
*Packet
,
1739 IN UINT8
*NvMapOverride
,
1740 IN UINTN NumberOfIfrImages
,
1741 OUT EFI_FILE_FORM_TAGS
**FileFormTagsHead
1746 EFI_IFR_BINARY
*BinaryData
;
1747 EFI_FILE_FORM_TAGS
*FileFormTags
;
1748 UINTN SizeOfNvStore
;
1749 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
1750 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
1751 EFI_VARIABLE_DEFINITION
*OverrideDefinition
;
1754 EFI_HII_VARIABLE_PACK_LIST
*NvMapListHead
;
1755 EFI_HII_VARIABLE_PACK_LIST
*NvMapListNode
;
1758 // Initialize some variables to avoid warnings
1761 *FileFormTagsHead
= NULL
;
1762 FileFormTags
= NULL
;
1763 gBinaryDataHead
= NULL
;
1764 Status
= EFI_SUCCESS
;
1765 FormCallback
= NULL
;
1769 if (NumberOfIfrImages
> 1) {
1770 NvMapOverride
= NULL
;
1773 for (HandleIndex
= 0; HandleIndex
< NumberOfIfrImages
; HandleIndex
+= 1) {
1775 // If the buffers are uninitialized, allocate them, otherwise work on the ->Next members
1777 if ((BinaryData
== NULL
) || (FileFormTags
== NULL
)) {
1779 // Allocate memory for our Binary Data
1781 BinaryData
= AllocateZeroPool (sizeof (EFI_IFR_BINARY
));
1782 ASSERT (BinaryData
);
1785 // Preserve the Head of what will be a linked-list.
1787 gBinaryDataHead
= BinaryData
;
1788 gBinaryDataHead
->Next
= NULL
;
1791 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], NULL
, BinaryData
);
1793 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], Packet
, BinaryData
);
1796 // Allocate memory for our File Form Tags
1798 FileFormTags
= AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS
));
1799 ASSERT (FileFormTags
);
1802 // Preserve the Head of what will be a linked-list.
1804 *FileFormTagsHead
= FileFormTags
;
1805 (*FileFormTagsHead
)->NextFile
= NULL
;
1809 // Allocate memory for our Binary Data linked-list
1810 // Each handle represents a Binary and we will store that data away.
1812 BinaryData
->Next
= AllocateZeroPool (sizeof (EFI_IFR_BINARY
));
1813 ASSERT (BinaryData
->Next
);
1815 BinaryData
= BinaryData
->Next
;
1816 BinaryData
->Next
= NULL
;
1819 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], NULL
, BinaryData
);
1821 Status
= GetIfrBinaryData (Hii
, Handle
[HandleIndex
], Packet
, BinaryData
);
1824 if (EFI_ERROR (Status
)) {
1825 return EFI_DEVICE_ERROR
;
1828 // Allocate memory for our FileFormTags linked-list
1829 // Each allocation reserves handle represents a Binary and we will store that data away.
1831 FileFormTags
->NextFile
= AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS
));
1832 ASSERT (FileFormTags
->NextFile
);
1834 FileFormTags
= FileFormTags
->NextFile
;
1839 // Tag Structure Initialization
1841 Status
= InitializeTagStructures (BinaryData
, FileFormTags
);
1843 VariableDefinition
= FileFormTags
->VariableDefinitions
;
1846 // Allocate memory for our NVRAM Maps for all of our variables
1848 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
1850 // Pad the fake variable size accordingly - this value should reflect the size of information that is not accounted by
1851 // the mainstream NVRAM variable such as DATE/TIME information that the browser needs to track but is saved to an RTC
1853 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableSize
+ VariableDefinition
->VariableFakeSize
);
1856 // In the case where a file has no "real" NV data, we should pad the buffer accordingly
1858 if (VariableDefinition
->VariableSize
== 0) {
1859 if (VariableDefinition
->VariableFakeSize
!= 0) {
1860 VariableDefinition
->NvRamMap
= AllocateZeroPool (VariableDefinition
->VariableFakeSize
);
1861 ASSERT (VariableDefinition
->NvRamMap
!= NULL
);
1864 VariableDefinition
->NvRamMap
= AllocateZeroPool (VariableDefinition
->VariableSize
);
1865 ASSERT (VariableDefinition
->NvRamMap
!= NULL
);
1868 if (VariableDefinition
->VariableFakeSize
!= 0) {
1869 VariableDefinition
->FakeNvRamMap
= AllocateZeroPool (VariableDefinition
->VariableFakeSize
);
1870 ASSERT (VariableDefinition
->FakeNvRamMap
!= NULL
);
1874 Status
= gBS
->HandleProtocol (
1875 (VOID
*) (UINTN
) FileFormTags
->FormTags
.Tags
[0].CallbackHandle
,
1876 &gEfiFormCallbackProtocolGuid
,
1877 (VOID
**) &FormCallback
1881 // Since we might have multiple variables, if there is an NvMapOverride we need to use the EFI_VARIABLE_DEFINITION
1882 // information as the information that we pass back and forth. NOTE that callbacks that are initiated will only have the
1883 // NVRAM data refreshed based on the op-code that initiated the callback. In other words, we will pass to the caller a single
1884 // NVRAM map for a single variable based on the op-code that the user selected.
1886 if (NvMapOverride
!= NULL
) {
1887 VariableDefinition
= FileFormTags
->VariableDefinitions
;
1888 OverrideDefinition
= ((EFI_VARIABLE_DEFINITION
*) NvMapOverride
);
1891 // Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified
1893 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
1894 if ((!CompareMem (VariableDefinition
->VariableName
, L
"Setup", 10)) && (VariableDefinition
->Next
== NULL
)) {
1895 if (VariableDefinition
->VariableSize
!= 0) {
1896 CopyMem (VariableDefinition
->NvRamMap
, NvMapOverride
, VariableDefinition
->VariableSize
);
1898 CopyMem (VariableDefinition
->NvRamMap
, NvMapOverride
, VariableDefinition
->VariableFakeSize
);
1902 VariableDefinition
->NvRamMap
= OverrideDefinition
->NvRamMap
;
1905 // There should NEVER be a ->Next for VariableDefinition and a NULL ->Next for the OverrideDefinition
1907 ASSERT (OverrideDefinition
->Next
);
1908 OverrideDefinition
= OverrideDefinition
->Next
;
1911 VariableDefinition
= FileFormTags
->VariableDefinitions
;
1914 // Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified
1916 for (; VariableDefinition
!= NULL
; VariableDefinition
= VariableDefinition
->Next
) {
1917 SizeOfNvStore
= VariableDefinition
->VariableSize
;
1920 // Getting the NvStore and placing it into our Global Data
1922 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
1923 Status
= FormCallback
->NvRead (
1925 VariableDefinition
->VariableName
,
1926 &VariableDefinition
->Guid
,
1929 (VOID
*) VariableDefinition
->NvRamMap
1932 Status
= gRT
->GetVariable (
1933 VariableDefinition
->VariableName
,
1934 &VariableDefinition
->Guid
,
1937 (VOID
*) VariableDefinition
->NvRamMap
1941 if (EFI_ERROR (Status
)) {
1943 // If there is a variable that exists already and it is larger than what we calculated the
1944 // storage needs to be, we must assume the variable size from GetVariable is correct and not
1945 // allow the truncation of the variable. It is very possible that the user who created the IFR
1946 // we are cracking is not referring to a variable that was in a previous map, however we cannot
1947 // allow it's truncation.
1949 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1951 // If the buffer was too small, we should have the expanded size requirement in SizeOfNvStore now.
1953 VariableDefinition
->VariableSize
= (UINT16
) SizeOfNvStore
;
1956 // Free the buffer that was allocated that was too small
1958 gBS
->FreePool (VariableDefinition
->NvRamMap
);
1959 gBS
->FreePool (VariableDefinition
->FakeNvRamMap
);
1961 VariableDefinition
->NvRamMap
= AllocateZeroPool (SizeOfNvStore
);
1962 VariableDefinition
->FakeNvRamMap
= AllocateZeroPool (SizeOfNvStore
+ VariableDefinition
->VariableFakeSize
);
1963 ASSERT (VariableDefinition
->NvRamMap
);
1964 ASSERT (VariableDefinition
->FakeNvRamMap
);
1966 if ((FormCallback
!= NULL
) && (FormCallback
->NvRead
!= NULL
)) {
1967 Status
= FormCallback
->NvRead (
1969 VariableDefinition
->VariableName
,
1970 &VariableDefinition
->Guid
,
1973 (VOID
*) VariableDefinition
->NvRamMap
1976 Status
= gRT
->GetVariable (
1977 VariableDefinition
->VariableName
,
1978 &VariableDefinition
->Guid
,
1981 (VOID
*) VariableDefinition
->NvRamMap
1986 // if the variable was not found, we will retrieve default values
1988 if (Status
== EFI_NOT_FOUND
) {
1990 if (0 == CompareMem (VariableDefinition
->VariableName
, L
"Setup", 10)) {
1992 NvMapListHead
= NULL
;
1994 Status
= Hii
->GetDefaultImage (Hii
, Handle
[HandleIndex
], EFI_IFR_FLAG_DEFAULT
, &NvMapListHead
);
1996 if (!EFI_ERROR (Status
)) {
1997 ASSERT_EFI_ERROR (NULL
!= NvMapListHead
);
1999 NvMapListNode
= NvMapListHead
;
2001 while (NULL
!= NvMapListNode
) {
2002 if (VariableDefinition
->VariableId
== NvMapListNode
->VariablePack
->VariableId
) {
2003 NvMap
= (VOID
*) ((CHAR8
*) NvMapListNode
->VariablePack
+ sizeof (EFI_HII_VARIABLE_PACK
) + NvMapListNode
->VariablePack
->VariableNameLength
);
2004 NvMapSize
= NvMapListNode
->VariablePack
->Header
.Length
- sizeof (EFI_HII_VARIABLE_PACK
) - NvMapListNode
->VariablePack
->VariableNameLength
;
2007 NvMapListNode
= NvMapListNode
->NextVariablePack
;
2011 // Free the buffer that was allocated.
2013 gBS
->FreePool (VariableDefinition
->NvRamMap
);
2014 gBS
->FreePool (VariableDefinition
->FakeNvRamMap
);
2017 // Allocate, copy the NvRamMap.
2019 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
- VariableDefinition
->VariableSize
);
2020 VariableDefinition
->VariableSize
= (UINT16
) NvMapSize
;
2021 VariableDefinition
->VariableFakeSize
= (UINT16
) (VariableDefinition
->VariableFakeSize
+ VariableDefinition
->VariableSize
);
2023 VariableDefinition
->NvRamMap
= AllocateZeroPool (VariableDefinition
->VariableSize
);
2024 VariableDefinition
->FakeNvRamMap
= AllocateZeroPool (NvMapSize
+ VariableDefinition
->VariableFakeSize
);
2026 CopyMem (VariableDefinition
->NvRamMap
, NvMap
, NvMapSize
);
2027 gBS
->FreePool (NvMapListHead
);
2031 Status
= EFI_SUCCESS
;
2037 InitializeTagStructures (BinaryData
, FileFormTags
);
2048 IN EFI_HII_PROTOCOL
*Hii
,
2049 IN EFI_HII_HANDLE HiiHandle
,
2050 IN EFI_IFR_PACKET
*Packet
,
2051 IN OUT EFI_IFR_BINARY
*BinaryData
2055 Routine Description:
2056 Fetch the Ifr binary data.
2059 Hii - Point to HII protocol.
2060 HiiHandle - Handle of Ifr to be fetched.
2061 Packet - Pointer to IFR packet.
2062 BinaryData - Buffer to copy the string into
2065 Returns the number of CHAR16 characters that were copied into the OutputString buffer.
2071 EFI_HII_PACKAGES
*PackageList
;
2074 UINT8
*RawFormBinary
;
2075 EFI_IFR_FORM_SET
*FormOp
;
2081 // Initialize the TitleToken to 0 just in case not found
2086 // Try for a 32K Buffer
2088 BufferSize
= 0x8000;
2091 // Allocate memory for our Form binary
2093 Buffer
= AllocateZeroPool (BufferSize
);
2096 if (Packet
== NULL
) {
2097 Status
= Hii
->GetForms (Hii
, HiiHandle
, 0, &BufferSize
, Buffer
);
2099 if (Status
== EFI_BUFFER_TOO_SMALL
) {
2101 gBS
->FreePool (Buffer
);
2104 // Allocate memory for our Form binary
2106 Buffer
= AllocatePool (BufferSize
);
2109 Status
= Hii
->GetForms (Hii
, HiiHandle
, 0, &BufferSize
, Buffer
);
2113 // Copies the data to local usable buffer
2115 CopyMem (Buffer
, Packet
->IfrData
, Packet
->IfrData
->Header
.Length
);
2118 // Register the string data with HII
2120 PackageList
= PreparePackages (2, NULL
, Packet
->IfrData
, Packet
->StringData
);
2122 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
2124 gBS
->FreePool (PackageList
);
2127 if (EFI_ERROR (Status
)) {
2131 // We now have the IFR binary in our Buffer
2133 BinaryData
->IfrPackage
= Buffer
;
2134 RawFormBinary
= (UINT8
*) ((CHAR8
*) (Buffer
) + sizeof (EFI_HII_PACK_HEADER
));
2135 BinaryData
->FormBinary
= (UINT8
*) ((CHAR8
*) (Buffer
) + sizeof (EFI_HII_PACK_HEADER
));
2136 BinaryData
->Handle
= HiiHandle
;
2139 // If a packet was passed in, remove the string data when exiting.
2141 if (Packet
!= NULL
) {
2142 BinaryData
->UnRegisterOnExit
= TRUE
;
2144 BinaryData
->UnRegisterOnExit
= FALSE
;
2147 // Walk through the FormSet Opcodes looking for the FormSet opcode
2148 // If we hit EFI_IFR_END_SET_OP we know we hit the end of the FormSet.
2150 for (Index
= 0; RawFormBinary
[Index
] != EFI_IFR_END_FORM_SET_OP
;) {
2151 FormOp
= (EFI_IFR_FORM_SET
*) &RawFormBinary
[Index
];
2152 Index
= (UINT16
) (Index
+ FormOp
->Header
.Length
);
2154 if (FormOp
->Header
.OpCode
== EFI_IFR_FORM_SET_OP
) {
2155 TitleToken
= FormOp
->FormSetTitle
;
2157 // If displaying FrontPage - set the flag signifying it
2159 switch (FormOp
->SubClass
) {
2160 case EFI_FRONT_PAGE_SUBCLASS
:
2161 FrontPageHandle
= HiiHandle
;
2164 gClassOfVfr
= FormOp
->SubClass
;
2167 // Match GUID to find out the function key setting. If match fail, use the default setting.
2169 for (Index2
= 0; Index2
< sizeof (gFunctionKeySettingTable
) / sizeof (FUNCTIION_KEY_SETTING
); Index2
++) {
2170 if (CompareGuid ((EFI_GUID
*)(UINTN
)&FormOp
->Guid
, &(gFunctionKeySettingTable
[Index2
].FormSetGuid
))) {
2172 // Update the function key setting.
2174 gFunctionKeySetting
= gFunctionKeySettingTable
[Index2
].KeySetting
;
2176 // Function key prompt can not be displayed if the function key has been disabled.
2178 if ((gFunctionKeySetting
& FUNCTION_ONE
) != FUNCTION_ONE
) {
2179 gFunctionOneString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2182 if ((gFunctionKeySetting
& FUNCTION_TWO
) != FUNCTION_TWO
) {
2183 gFunctionTwoString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2186 if ((gFunctionKeySetting
& FUNCTION_NINE
) != FUNCTION_NINE
) {
2187 gFunctionNineString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2190 if ((gFunctionKeySetting
& FUNCTION_TEN
) != FUNCTION_TEN
) {
2191 gFunctionTenString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
2198 BinaryData
->TitleToken
= TitleToken
;
2203 EFI_HANDLE PrintHandle
= NULL
;
2204 EFI_PRINT_PROTOCOL mPrintProtocol
= { UnicodeVSPrint
};
2212 return gBS
->InstallProtocolInterface (
2214 &gEfiPrintProtocolGuid
,
2215 EFI_NATIVE_INTERFACE
,