boot.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,972 行 · 第 1/5 页
C
1,972 行
AllocateSpecialBootOption (&BootMenu, L"Delete All Boot Options", CON_UNSELECTED, DELETE_MENU_ALL);
SaveNvramContext =
AllocateSpecialBootOption (&BootMenu, L"Save Settings to NVRAM", CON_UNSELECTED, DELETE_MENU_SAVE_NVRAM);
DeleteHelpContext =
AllocateSpecialBootOption (&BootMenu, L"Help", CON_UNSELECTED, DELETE_MENU_HELP);
DeleteExitContext =
AllocateSpecialBootOption (&BootMenu, L"Exit", CON_UNSELECTED, DELETE_MENU_EXIT);
ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &MaxColumn, &ScreenSize);
EndRow = ScreenSize - BootMenu.FooterHeight - 1;
BootMenu.Selection = NULL;
NVRAMNeedsUpdating = FALSE;
for (Done = FALSE, ResultContext = NULL; !Done;) {
PreviousResultContext = ResultContext;
ResultContext = MenuDisplay (&BootMenu, &Key);
if (!ResultContext) {
Done = TRUE;
break;
}
switch (Key.UnicodeChar){
case CHAR_CARRIAGE_RETURN:
MenuOption = ResultContext->MenuOption;
break;
case 'D':
case 'd':
if (ResultContext->MenuOption == BOOT_MENU_SELECTION)
MenuOption = BOOT_MENU_SELECTION;
else
MenuOption = -1;
break;
case 'A':
case 'a':
MenuOption = DELETE_MENU_ALL;
break;
default:
MenuOption = -1;
} // end switch
if (MenuOption == DELETE_MENU_EXIT) {
if (NVRAMNeedsUpdating) {
PrintAt (ResultContext->Menu->Col, ResultContext->Menu->Row + 2, L"NVRAM Not updated. Save NVRAM? [Y to save, N to ignore]");
WaitForSingleEvent (ST->ConIn->WaitForKey, 0);
ST->ConIn->ReadKeyStroke (ST->ConIn, &Key);
if (Key.UnicodeChar == 'Y' || Key.UnicodeChar == 'y') {
MenuOption = DELETE_MENU_SAVE_NVRAM;
}
}
Done = TRUE;
}
switch (MenuOption) {
case DELETE_MENU_ALL:
BootMenu.Selection = NULL;
DeleteAllBootOptions (&NVRAMNeedsUpdating);
break;
case DELETE_MENU_EXIT:
break;
case DELETE_MENU_HELP:
PrintMenuHelp(&DeleteHelpMenu,DeleteMenuHelpStr);
break;
case DELETE_MENU_SAVE_NVRAM:
Status = SetNvramForBootMenu (&BootMenu);
if (EFI_ERROR(Status)) {
PrintAt (ResultContext->Menu->Col, ResultContext->Menu->Row + 3, L"NVRAM update failed");
} else {
NVRAMNeedsUpdating = FALSE;
}
break;
case BOOT_MENU_SELECTION:
Exit = FALSE;
while (!Exit) {
ST->ConOut->SetAttribute (ST->ConOut, BootMenu.ReverseScreenAttribute);
PrintAt(BootMenu.Col,EndRow,L"Delete selected Boot Option [Y-Yes N-No]: ");
WaitForSingleEvent (ST->ConIn->WaitForKey, 0);
ST->ConIn->ReadKeyStroke (ST->ConIn, &Key);
ST->ConOut->SetAttribute (ST->ConOut, BootMenu.ScreenAttribute);
if (Key.UnicodeChar == 'Y' || Key.UnicodeChar == 'y') {
BootMenu.Selection = NULL;
if (ResultContext->OptionNumber != NEWADDITION_OPTIONNUMBER)
NVRAMNeedsUpdating = TRUE;
FreeSpecificBootMenuOption(&BootMenu, ResultContext);
Exit = TRUE;
}
if (Key.UnicodeChar == 'N' || Key.UnicodeChar == 'n') {
Exit = TRUE;
}
}
break;
default:
break;
}
}
FreeSpecificBootMenuOption(&BootMenu, DeleteAllContext);
FreeSpecificBootMenuOption(&BootMenu, SaveNvramContext);
FreeSpecificBootMenuOption(&BootMenu, DeleteHelpContext);
FreeSpecificBootMenuOption(&BootMenu, DeleteExitContext);
ST->ConOut->ClearScreen (ST->ConOut);
return EFI_SUCCESS;
}
EFI_STATUS
DeleteAllBootOptions (
OUT BOOLEAN *UpdateNvram)
{
EFI_INPUT_KEY Key;
SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut;
SIMPLE_INPUT_INTERFACE *ConIn;
UINTN EndRow;
UINTN MaxColumn, ScreenSize;
BOOLEAN Exit,DeleteAll;
MENU_OPTION *MenuOption;
BOOT_MENU_CONTEXT *BootContext;
LIST_ENTRY *List;
UINTN Count;
ConOut = ST->ConOut;
ConIn = ST->ConIn;
ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &MaxColumn, &ScreenSize);
//
// check to see if we have atleast one boot option to delete
//
Count = 0;
List = BootMenu.Head.Flink;
while (List != &BootMenu.Head) {
MenuOption = CR(List, MENU_OPTION, Link, MENU_OPTION_SIGNATURE);
// get the next list in line
List = List->Flink;
BootContext = (BOOT_MENU_CONTEXT *)MenuOption->Context;
if( BootContext->MenuOption == BOOT_MENU_SELECTION) {
Count = 1;
break;
}
}
//
// Put prompt for delete
//
EndRow = ScreenSize - BootMenu.FooterHeight - 1;
Exit = FALSE;
DeleteAll = FALSE;
*UpdateNvram = FALSE;
while (!Exit && Count) {
ConOut->SetAttribute (ConOut, BootMenu.ReverseScreenAttribute);
PrintAt(BootMenu.Col,EndRow,L"Delete ALL of above Boot Options [Y-Yes N-No]: ");
WaitForSingleEvent (ConIn->WaitForKey, 0);
ConIn->ReadKeyStroke (ConIn, &Key);
ConOut->SetAttribute (ConOut, BootMenu.ScreenAttribute);
if (Key.UnicodeChar == 'Y' || Key.UnicodeChar == 'y') {
DeleteAll = TRUE;
Exit = TRUE;
}
if (Key.UnicodeChar == 'N' || Key.UnicodeChar == 'n') {
Exit = TRUE;
}
}
//
// Check and Delete the boot options
//
if ( DeleteAll) {
List = BootMenu.Head.Flink;
while (List != &BootMenu.Head) {
MenuOption = CR(List, MENU_OPTION, Link, MENU_OPTION_SIGNATURE);
// get the next list in case we end up freeing the current one
List = List->Flink;
BootContext = (BOOT_MENU_CONTEXT *)MenuOption->Context;
if ((BootContext != NULL) && (BootContext->MenuOption == BOOT_MENU_SELECTION)) {
//
// Delete the variable from storage
//
if (BootContext->OptionNumber != NEWADDITION_OPTIONNUMBER) {
*UpdateNvram = TRUE;
}
FreeSpecificBootMenuOption(&BootMenu, BootContext);
}
}
//
// Clear BootNext and BootOrder as well
//
}
return EFI_SUCCESS;
}
EFI_STATUS
Bmnt_DisplayBootNextMenu (
VOID
)
{
BOOT_MENU_CONTEXT *ResultContext;
BOOT_MENU_CONTEXT *PreviousResultContext;
BOOT_MENU_CONTEXT *SaveNvramContext;
BOOT_MENU_CONTEXT *ResetBootNext;
BOOT_MENU_CONTEXT *BootNextHelpContext;
BOOT_MENU_CONTEXT *BootNextExitContext;
BOOLEAN NVRAMNeedsUpdating;
UINTN MenuOption;
EFI_INPUT_KEY Key;
EFI_STATUS Status;
BOOLEAN Done;
UINTN EndRow;
UINTN MaxColumn, ScreenSize;
BOOLEAN Exit;
CHAR16 *Header = L"%EManage BootNext setting. Select an Operation\n\n";
//
// initialize header text
//
FreeBootOrderMenuOfVariables();
InitializeBootOrderMenuFromVariable();
BootMenu.Header = Header;
ResetBootNext =
AllocateSpecialBootOption (&BootMenu, L"Reset BootNext Setting", CON_UNSELECTED, BOOTNEXT_MENU_RESET);
SaveNvramContext =
AllocateSpecialBootOption (&BootMenu, L"Save Settings to NVRAM", CON_UNSELECTED, BOOTNEXT_MENU_SAVE_NVRAM);
BootNextHelpContext =
AllocateSpecialBootOption (&BootMenu, L"Help", CON_UNSELECTED, BOOTNEXT_MENU_HELP);
BootNextExitContext =
AllocateSpecialBootOption (&BootMenu, L"Exit", CON_UNSELECTED, BOOTNEXT_MENU_EXIT);
ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &MaxColumn, &ScreenSize);
EndRow = ScreenSize - BootMenu.FooterHeight - 1;
BootMenu.Selection = NULL;
NVRAMNeedsUpdating = FALSE;
for (Done = FALSE, ResultContext = NULL; !Done;) {
PreviousResultContext = ResultContext;
ResultContext = MenuDisplay (&BootMenu, &Key);
if (!ResultContext) {
Done = TRUE;
break;
}
switch (Key.UnicodeChar){
case CHAR_CARRIAGE_RETURN:
MenuOption = ResultContext->MenuOption;
break;
case 'B':
case 'b':
if (ResultContext->MenuOption == BOOT_MENU_SELECTION)
MenuOption = BOOT_MENU_SELECTION;
else
MenuOption = -1;
break;
case 'R':
case 'r':
MenuOption = BOOTNEXT_MENU_RESET;
break;
default:
MenuOption = -1;
} // end switch
if (MenuOption == BOOTNEXT_MENU_EXIT) {
if (NVRAMNeedsUpdating) {
PrintAt (ResultContext->Menu->Col, ResultContext->Menu->Row + 2, L"NVRAM Not updated. Save NVRAM? [Y to save, N to ignore]");
WaitForSingleEvent (ST->ConIn->WaitForKey, 0);
ST->ConIn->ReadKeyStroke (ST->ConIn, &Key);
if (Key.UnicodeChar == 'Y' || Key.UnicodeChar == 'y') {
MenuOption = BOOTNEXT_MENU_SAVE_NVRAM;
}
}
Done = TRUE;
}
switch (MenuOption) {
case BOOTNEXT_MENU_RESET:
ResetBootNextOption (&NVRAMNeedsUpdating, TRUE);
break;
case BOOTNEXT_MENU_EXIT:
break;
case BOOTNEXT_MENU_HELP:
PrintMenuHelp(&BootNextHelpMenu,BootNextMenuHelpStr);
break;
case BOOTNEXT_MENU_SAVE_NVRAM:
Status = SetNvramForBootMenu (&BootMenu);
if (EFI_ERROR(Status)) {
PrintAt (ResultContext->Menu->Col, ResultContext->Menu->Row + 3, L"NVRAM update failed");
} else {
NVRAMNeedsUpdating = FALSE;
}
break;
case BOOT_MENU_SELECTION:
Exit = FALSE;
while (!Exit) {
ST->ConOut->SetAttribute (ST->ConOut, BootMenu.ReverseScreenAttribute);
PrintAt(BootMenu.Col,EndRow,L"Enter selected Boot Option as 'BootNext' [Y-Yes N-No]: ");
WaitForSingleEvent (ST->ConIn->WaitForKey, 0);
ST->ConIn->ReadKeyStroke (ST->ConIn, &Key);
ST->ConOut->SetAttribute (ST->ConOut, BootMenu.ScreenAttribute);
if (Key.UnicodeChar == 'Y' || Key.UnicodeChar == 'y') {
ResetBootNextOption (&NVRAMNeedsUpdating,FALSE);
if (ResultContext->OptionNumber != NEWADDITION_OPTIONNUMBER)
NVRAMNeedsUpdating = TRUE;
ResultContext->IsBootNext = TRUE;
Exit = TRUE;
}
if (Key.UnicodeChar == 'N' || Key.UnicodeChar == 'n') {
Exit = TRUE;
}
}
break;
default:
break;
}
}
FreeSpecificBootMenuOption(&BootMenu, ResetBootNext);
FreeSpecificBootMenuOption(&BootMenu, SaveNvramContext);
FreeSpecificBootMenuOption(&BootMenu, BootNextHelpContext);
FreeSpecificBootMenuOption(&BootMenu, BootNextExitContext);
ST->ConOut->ClearScreen (ST->ConOut);
return EFI_SUCCESS;
}
EFI_STATUS
ResetBootNextOption (
OUT BOOLEAN *UpdateNvram,
IN BOOLEAN Prompt
)
{
EFI_INPUT_KEY Key;
SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut;
SIMPLE_INPUT_INTERFACE *ConIn;
UINTN EndRow, Count;
UINTN MaxColumn, ScreenSize;
MENU_OPTION *MenuOption;
BOOT_MENU_CONTEXT *BootContext;
LIST_ENTRY *List;
ConOut = ST->ConOut;
ConIn = ST->ConIn;
ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &MaxColumn, &ScreenSize);
Count = 0;
List = BootMenu.Head.Flink;
while (List != &BootMenu.Head) {
MenuOption = CR(List, MENU_OPTION, Link, MENU_OPTION_SIGNATURE);
// get the next list in case we end up freeing the current one
List = List->Flink;
BootContext = (BOOT_MENU_CONTEXT *)MenuOption->Context;
if ((BootContext != NULL) && (BootContext->MenuOption == BOOT_MENU_SELECTION)
&& (BootContext->IsBootNext)) {
if (BootContext->OptionNumber != NEWADDITION_OPTIONNUMBER) {
*UpdateNvram = TRUE;
}
Count = 1 ;
BootContext->IsBootNext = FALSE;
}
}
if(Count && Prompt) {
//
// Print message
//
EndRow = ScreenSize - BootMenu.FooterHeight - 1;
ConOut->SetAttribute (ConOut, BootMenu.ReverseScreenAttribute);
PrintAt(BootMenu.Col,EndRow,L"'BootNext' variable cleared. Press any key...");
WaitForSingleEvent (ConIn->WaitForKey, 0);
ConIn->ReadKeyStroke (ConIn, &Key);
ConOut->SetAttribute (ConOut, BootMenu.ScreenAttribute);
}
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?