ui.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,158 行 · 第 1/5 页
C
2,158 行
IN EFI_FILE_FORM_TAGS *FileFormTagsHead,
IN CHAR16 *FormattedString,
IN CHAR16 *OptionString
)
/*++
Routine Description:
Used to remove the allocated data instances
Arguments:
Returns:
--*/
{
EFI_FILE_FORM_TAGS *FileForm;
EFI_FILE_FORM_TAGS *PreviousFileForm;
EFI_FORM_TAGS *FormTags;
EFI_FORM_TAGS *PreviousFormTags;
EFI_IFR_BINARY *IfrBinary;
EFI_IFR_BINARY *PreviousIfrBinary;
EFI_INCONSISTENCY_DATA *Inconsistent;
EFI_VARIABLE_DEFINITION *VariableDefinition;
EFI_VARIABLE_DEFINITION *PreviousVariableDefinition;
VOID *Buffer;
UINTN Index;
FileForm = FileFormTagsHead;
if (FormattedString != NULL) {
gBS->FreePool (FormattedString);
}
if (OptionString != NULL) {
gBS->FreePool (OptionString);
}
for (; FileForm != NULL;) {
PreviousFileForm = NULL;
//
// Advance FileForm to the last entry
//
for (; FileForm->NextFile != NULL; FileForm = FileForm->NextFile) {
PreviousFileForm = FileForm;
}
FormTags = &FileForm->FormTags;
for (; FormTags != NULL;) {
FormTags = &FileForm->FormTags;
PreviousFormTags = NULL;
//
// Advance FormTags to the last entry
//
for (; FormTags->Next != NULL; FormTags = FormTags->Next) {
PreviousFormTags = FormTags;
}
//
// Walk through each of the tags and free the IntList allocation
//
for (Index = 0; FormTags->Tags[Index].Operand != EFI_IFR_END_FORM_OP; Index++) {
//
// It is more than likely that the very last page will contain an end formset
//
if (FormTags->Tags[Index].Operand == EFI_IFR_END_FORM_SET_OP) {
break;
}
if (FormTags->Tags[Index].IntList != NULL) {
gBS->FreePool (FormTags->Tags[Index].IntList);
}
}
if (PreviousFormTags != NULL) {
gBS->FreePool (FormTags->Tags);
FormTags = PreviousFormTags;
gBS->FreePool (FormTags->Next);
FormTags->Next = NULL;
} else {
gBS->FreePool (FormTags->Tags);
FormTags = NULL;
}
}
//
// Last FileForm entry's Inconsistent database
//
Inconsistent = FileForm->InconsistentTags;
//
// Advance Inconsistent to the last entry
//
for (; Inconsistent->Next != NULL; Inconsistent = Inconsistent->Next)
;
for (; Inconsistent != NULL;) {
//
// Preserve the Previous pointer
//
Buffer = (VOID *) Inconsistent->Previous;
//
// Free the current entry
//
gBS->FreePool (Inconsistent);
//
// Restore the Previous pointer
//
Inconsistent = (EFI_INCONSISTENCY_DATA *) Buffer;
}
VariableDefinition = FileForm->VariableDefinitions;
for (; VariableDefinition != NULL;) {
VariableDefinition = FileForm->VariableDefinitions;
PreviousVariableDefinition = NULL;
//
// Advance VariableDefinitions to the last entry
//
for (; VariableDefinition->Next != NULL; VariableDefinition = VariableDefinition->Next) {
PreviousVariableDefinition = VariableDefinition;
}
gBS->FreePool (VariableDefinition->VariableName);
gBS->FreePool (VariableDefinition->NvRamMap);
gBS->FreePool (VariableDefinition->FakeNvRamMap);
if (PreviousVariableDefinition != NULL) {
VariableDefinition = PreviousVariableDefinition;
gBS->FreePool (VariableDefinition->Next);
VariableDefinition->Next = NULL;
} else {
gBS->FreePool (VariableDefinition);
VariableDefinition = NULL;
}
}
if (PreviousFileForm != NULL) {
FileForm = PreviousFileForm;
gBS->FreePool (FileForm->NextFile);
FileForm->NextFile = NULL;
} else {
gBS->FreePool (FileForm);
FileForm = NULL;
}
}
IfrBinary = gBinaryDataHead;
for (; IfrBinary != NULL;) {
IfrBinary = gBinaryDataHead;
PreviousIfrBinary = NULL;
//
// Advance IfrBinary to the last entry
//
for (; IfrBinary->Next != NULL; IfrBinary = IfrBinary->Next) {
PreviousIfrBinary = IfrBinary;
}
gBS->FreePool (IfrBinary->IfrPackage);
if (PreviousIfrBinary != NULL) {
IfrBinary = PreviousIfrBinary;
gBS->FreePool (IfrBinary->Next);
IfrBinary->Next = NULL;
} else {
gBS->FreePool (IfrBinary);
IfrBinary = NULL;
}
}
gBS->FreePool (gPreviousValue);
gPreviousValue = NULL;
//
// Free Browser Strings
//
gBS->FreePool (gPressEnter);
gBS->FreePool (gConfirmError);
gBS->FreePool (gConfirmPassword);
gBS->FreePool (gPromptForNewPassword);
gBS->FreePool (gPromptForPassword);
gBS->FreePool (gToggleCheckBox);
gBS->FreePool (gNumericInput);
gBS->FreePool (gMakeSelection);
gBS->FreePool (gMoveHighlight);
gBS->FreePool (gEscapeString);
gBS->FreePool (gEnterCommitString);
gBS->FreePool (gEnterString);
gBS->FreePool (gFunctionOneString);
gBS->FreePool (gFunctionTwoString);
gBS->FreePool (gFunctionNineString);
gBS->FreePool (gFunctionTenString);
return ;
}
BOOLEAN
SelectionsAreValid (
IN UI_MENU_OPTION *MenuOption,
IN EFI_FILE_FORM_TAGS *FileFormTagsHead
)
/*++
Routine Description:
Initiate late consistency checks against the current page.
Arguments:
None
Returns:
--*/
{
EFI_LIST_ENTRY *Link;
EFI_TAG *Tag;
EFI_FILE_FORM_TAGS *FileFormTags;
CHAR16 *StringPtr;
CHAR16 NullCharacter;
EFI_STATUS Status;
UINTN Index;
UINT16 *NvRamMap;
STRING_REF PopUp;
EFI_INPUT_KEY Key;
EFI_VARIABLE_DEFINITION *VariableDefinition;
StringPtr = L"\0";
NullCharacter = CHAR_NULL;
FileFormTags = FileFormTagsHead;
for (Index = 0; Index < MenuOption->IfrNumber; Index++) {
FileFormTags = FileFormTags->NextFile;
}
for (Link = Menu.ForwardLink; Link != &Menu; Link = Link->ForwardLink) {
MenuOption = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
Tag = MenuOption->ThisTag;
ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);
NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];
//
// If the op-code has a late check, ensure consistency checks are now applied
//
if (Tag->Flags & EFI_IFR_FLAG_LATE_CHECK) {
if (ValueIsNotValid (TRUE, 0, Tag, FileFormTags, &PopUp)) {
if (PopUp != 0x0000) {
StringPtr = GetToken (PopUp, MenuOption->Handle);
CreatePopUp (GetStringWidth (StringPtr) / 2, 3, &NullCharacter, StringPtr, &NullCharacter);
do {
Status = WaitForKeyStroke (&Key);
switch (Key.UnicodeChar) {
case CHAR_CARRIAGE_RETURN:
//
// Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth
//
EfiCopyMem (NvRamMap, &Tag->OldValue, Tag->StorageWidth);
gBS->FreePool (StringPtr);
break;
default:
break;
}
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
}
return FALSE;
}
}
}
return TRUE;
}
UINT16
GetWidth (
IN EFI_TAG *Tag,
IN EFI_HII_HANDLE Handle
)
/*++
Routine Description:
Get the supported width for a particular op-code
Arguments:
Tag - The Tag structure passed in.
Handle - The handle in the HII database being used
Returns:
Returns the number of CHAR16 characters that is support.
--*/
{
CHAR16 *String;
UINTN Size;
Size = 0x00;
//
// See if the second text parameter is really NULL
//
if ((Tag->Operand == EFI_IFR_TEXT_OP) && (Tag->TextTwo != 0)) {
String = GetToken (Tag->TextTwo, Handle);
Size = EfiStrLen (String);
gBS->FreePool (String);
}
if ((Tag->Operand == EFI_IFR_SUBTITLE_OP) ||
(Tag->Operand == EFI_IFR_REF_OP) ||
(Tag->Operand == EFI_IFR_PASSWORD_OP) ||
(Tag->Operand == EFI_IFR_STRING_OP) ||
(Tag->Operand == EFI_IFR_INVENTORY_OP) ||
//
// Allow a wide display if text op-code and no secondary text op-code
//
((Tag->Operand == EFI_IFR_TEXT_OP) && (Size == 0x0000))
) {
return (UINT16) (gPromptBlockWidth + gOptionBlockWidth);
} else {
return (UINT16) gPromptBlockWidth;
}
}
UINT16
GetLineByWidth (
IN CHAR16 *InputString,
IN UINT16 LineWidth,
IN OUT UINTN *Index,
OUT CHAR16 **OutputString
)
/*++
Routine Description:
Will copy LineWidth amount of a string in the OutputString buffer and return the
number of CHAR16 characters that were copied into the OutputString buffer.
Arguments:
InputString - String description for this option.
LineWidth - Width of the desired string to extract in CHAR16 characters
Index - Where in InputString to start the copy process
OutputString - Buffer to copy the string into
Returns:
Returns the number of CHAR16 characters that were copied into the OutputString buffer.
--*/
{
static BOOLEAN Finished;
UINT16 Count;
UINT16 Count2;
if (Finished) {
Finished = FALSE;
return (UINT16) 0;
}
Count = LineWidth;
Count2 = 0;
*OutputString = EfiLibAllocateZeroPool (((UINTN) (LineWidth + 1) * 2));
//
// Ensure we have got a valid buffer
//
if (*OutputString != NULL) {
//
//NARROW_CHAR can not be printed in screen, so if a line only contain the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line in Screen.
//To avoid displaying this empty line in screen, just skip the two CHARs here.
//
if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
*Index = *Index + 2;
}
//
// Fast-forward the string and see if there is a carriage-return in the string
//
for (; (InputString[*Index + Count2] != CHAR_CARRIAGE_RETURN) && (Count2 != LineWidth); Count2++)
;
//
// Copy the desired LineWidth of data to the output buffer.
// Also make sure that we don't copy more than the string.
// Also make sure that if there are linefeeds, we account for them.
//
if ((EfiStrSize (&InputString[*Index]) <= ((UINTN) (LineWidth + 1) * 2)) &&
(EfiStrSize (&InputString[*Index]) <= ((UINTN) (Count2 + 1) * 2))
) {
//
// Convert to CHAR16 value and show that we are done with this operation
//
LineWidth = (UINT16) ((EfiStrSize (&InputString[*Index]) - 2) / 2);
if (LineWidth != 0) {
Finished = TRUE;
}
} else {
if (Count2 == LineWidth) {
//
// Rewind the string from the maximum size until we see a space to break the line
//
for (; (InputString[*Index + LineWidth] != CHAR_SPACE) && (LineWidth != 0); LineWidth--)
;
if (LineWidth == 0) {
LineWidth = Count;
}
} else {
LineWidth = Count2;
}
}
EfiCopyMem (*OutputString, &InputString[*Index], LineWidth * 2);
//
// If currently pointing to a space, increment the index to the first non-space character
//
for (;
(InputString[*Index + LineWidth] == CHAR_SPACE) || (InputString[*Index + LineWidth] == CHAR_CARRIAGE_RETURN);
(*Index)++
)
;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?