console.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 771 行 · 第 1/2 页
C
771 行
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
console.c
Abstract:
handles console redirection from bootmanager
Revision History
--*/
#include "menu.h"
typedef enum {
UnusedMenuEntry,
ConsoleMenuOut,
ConsoleMenuIn,
ConsoleMenuError
} TYPE_OF_DISPLAY_CONSOLE_MENU;
//
// BugBug: It smells like a lib function
//
//--------------------------------------
BOOLEAN
MatchDevicePaths (
IN EFI_DEVICE_PATH *Multi,
IN EFI_DEVICE_PATH *Single
);
EFI_DEVICE_PATH *
DuplicateDevicePathInstance (
IN EFI_DEVICE_PATH *DevPath
);
//----------------------------------------
EFI_STATUS
SetNvramForConsoleMenu (
IN EFI_MENU *Menu,
IN CHAR16 *VarName,
IN TYPE_OF_DISPLAY_CONSOLE_MENU MenuType
);
BOOLEAN
CheckIfSelectionAllowed (
IN EFI_MENU *Menu,
IN TYPE_OF_DISPLAY_CONSOLE_MENU CurrentMenuType,
IN CONSOLE_MENU_CONTEXT *SelMenuContext
);
BOOLEAN
VerifyDevicePaths (
IN EFI_DEVICE_PATH *CurSelDevicePath,
IN EFI_DEVICE_PATH *PrevSelDevicePath
);
VOID
ConsoleContextPrint (
IN struct _MENU_OPTION *MenuOption,
IN VOID *Context,
IN UINTN *Row,
IN UINTN Column
);
CONSOLE_MENU_CONTEXT *
AllocateSpecialMenuOption (
IN EFI_MENU *Menu,
IN CHAR16 *String,
IN UINTN Attribute,
IN UINTN Option
);
EFI_STATUS
DisplayConsoleMenu (
IN TYPE_OF_DISPLAY_CONSOLE_MENU MenuType,
IN CHAR16 *Header,
IN CHAR16 *Footer
);
VOID
FreeConsoleMenu (
IN EFI_MENU *Menu
);
EFI_DEVICE_PATH *
DuplicateDevicePathInstance (
IN EFI_DEVICE_PATH *DevPath
);
VOID
ToggleSelectionStr(
IN EFI_MENU *Menu,
IN CONSOLE_MENU_CONTEXT *SelMenuContext,
IN BOOLEAN Active
);
EFI_MENU ConsoleMenu = {
MENU_SIGNATURE, NULL,
4, CON_UNSELECTED, CON_ACTIVE_SELECTION,
TRUE, 10,
L"%ESelect an Operation\n\n",
L" ", 4,
NULL, NULL, NULL, NULL, NULL, TRUE, 0, MENU_ENTRY_FORMAT
};
EFI_STATUS
Bmnt_DisplayConsoleOutMenu ()
{
return DisplayConsoleMenu (
ConsoleMenuOut,
L"Select the Console Output Device(s)\n\n",
NULL
);
}
EFI_STATUS
Bmnt_DisplayConsoleInMenu ()
{
return DisplayConsoleMenu (
ConsoleMenuIn,
L"Select the Console Input Device(s)\n\n",
NULL
);
}
EFI_STATUS
Bmnt_DisplayStdErrorMenu ()
{
return DisplayConsoleMenu (
ConsoleMenuError,
L"Select the Standard Error Device\n\n",
NULL
);
}
EFI_DEVICE_PATH *
DuplicateDevicePathInstance (
IN EFI_DEVICE_PATH *DevPath
)
{
EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp;
UINTN Size;
//
// get the size of an instance from the input
//
Temp = DevPath;
DevicePathInst = DevicePathInstance (&Temp, &Size);
//
// Make a copy and set proper end type
//
NewDevPath = NULL;
if (Size) {
NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
}
if (NewDevPath) {
CopyMem (NewDevPath, DevicePathInst, Size);
Temp = (EFI_DEVICE_PATH *) (((UINT8 *) NewDevPath) + Size);
SetDevicePathEndNode(Temp);
}
return NewDevPath;
}
EFI_STATUS
InitializeConsoleMenuFromVariable (
IN TYPE_OF_DISPLAY_CONSOLE_MENU MenuType,
IN OUT EFI_MENU *ConMenu
)
{
CHAR16 Buffer[1];
CONSOLE_MENU_CONTEXT *Context;
EFI_DEVICE_PATH *OutDevicePath;
EFI_DEVICE_PATH *InpDevicePath;
EFI_DEVICE_PATH *ErrDevicePath;
EFI_DEVICE_PATH *PrevSelDevicePath, *AllDevicePath;
EFI_DEVICE_PATH *Multi, *DevicePathInst;
UINTN Size;
CHAR16 *VarString;
OutDevicePath = LibGetVariable (VarConsoleOut, &EfiGlobalVariable);
InpDevicePath = LibGetVariable (VarConsoleInp, &EfiGlobalVariable);
ErrDevicePath = LibGetVariable (VarErrorOut, &EfiGlobalVariable);
switch (MenuType) {
case ConsoleMenuOut:
PrevSelDevicePath = OutDevicePath;
AllDevicePath = LibGetVariable (VarConsoleOutDev, &EfiGlobalVariable);
VarString = VarConsoleOut;
break;
case ConsoleMenuIn:
PrevSelDevicePath = InpDevicePath;
AllDevicePath = LibGetVariable (VarConsoleInpDev, &EfiGlobalVariable);
VarString = VarConsoleInp;
break;
case ConsoleMenuError:
PrevSelDevicePath = ErrDevicePath;
AllDevicePath = LibGetVariable (VarErrorOutDev, &EfiGlobalVariable);
VarString = VarErrorOut;
break;
default:
ASSERT(FALSE);
};
InitializeListHead (&ConMenu->Head);
//
// get all instances from the BS variable
//
Multi = AllDevicePath;
while (DevicePathInst = DevicePathInstance (&Multi, &Size)) {
Context = AllocateZeroPool (sizeof(CONSOLE_MENU_CONTEXT));
ASSERT (Context);
Context->MenuOption = CON_MENU_CONSOLE;
Context->DevicePath = DuplicateDevicePathInstance(DevicePathInst);
Context->ActiveConsole = MatchDevicePaths (PrevSelDevicePath, Context->DevicePath);
Context->Menu = AllocateMenuOption (ConMenu, Buffer, CON_UNSELECTED, Context);
}
if (AllDevicePath) {
FreePool (AllDevicePath);
}
if (OutDevicePath) {
FreePool (OutDevicePath);
}
if (InpDevicePath) {
FreePool (InpDevicePath);
}
if (ErrDevicePath) {
FreePool (ErrDevicePath);
}
return EFI_SUCCESS;
}
EFI_STATUS
DisplayConsoleMenu (
IN TYPE_OF_DISPLAY_CONSOLE_MENU MenuType,
IN CHAR16 *Header,
IN CHAR16 *Footer
)
{
CHAR16 Buffer[MAX_CHAR];
CONSOLE_MENU_CONTEXT *ResultContext;
CONSOLE_MENU_CONTEXT *PreviousResultContext;
CONSOLE_MENU_CONTEXT *Context;
EFI_INPUT_KEY Key;
UINTN Attribute;
EFI_DEVICE_PATH *OutDevicePath;
EFI_DEVICE_PATH *InpDevicePath;
EFI_DEVICE_PATH *ErrDevicePath;
EFI_DEVICE_PATH *PrevSelDevicePath, *AllDevicePath;
EFI_DEVICE_PATH *Multi, *DevicePathInst;
UINTN Size;
// EFI_GUID *CorGuid;
BOOLEAN Done;
UINTN ActiveConsoleCount;
// EFI_GUID *DeviceGuid;
CHAR16 *VarString;
BOOLEAN NVRAMNeedsUpdating;
UINTN MenuOption;
EFI_STATUS Status;
OutDevicePath = LibGetVariable (VarConsoleOut, &EfiGlobalVariable);
InpDevicePath = LibGetVariable (VarConsoleInp, &EfiGlobalVariable);
ErrDevicePath = LibGetVariable (VarErrorOut, &EfiGlobalVariable);
ActiveConsoleCount = 0;
switch (MenuType) {
case ConsoleMenuOut:
// DeviceGuid = &TextOutProtocol;
// CorGuid = &TextInProtocol;
PrevSelDevicePath = OutDevicePath;
AllDevicePath = LibGetVariable (VarConsoleOutDev, &EfiGlobalVariable);
VarString = VarConsoleOut;
break;
case ConsoleMenuIn:
// DeviceGuid = &TextInProtocol,
// CorGuid = &TextOutProtocol;
PrevSelDevicePath = InpDevicePath;
AllDevicePath = LibGetVariable (VarConsoleInpDev, &EfiGlobalVariable);
VarString = VarConsoleInp;
break;
case ConsoleMenuError:
// DeviceGuid = &TextOutProtocol,
// CorGuid = &TextInProtocol;
PrevSelDevicePath = ErrDevicePath;
AllDevicePath = LibGetVariable (VarErrorOutDev, &EfiGlobalVariable);
VarString = VarErrorOut;
break;
default:
ASSERT(FALSE);
};
ConsoleMenu.BottomOfPage = NULL;
InitializeListHead (&ConsoleMenu.Head);
//
// get all instances from the BS variable
//
Multi = AllDevicePath;
while (DevicePathInst = DevicePathInstance (&Multi, &Size)) {
Context = AllocateZeroPool (sizeof(CONSOLE_MENU_CONTEXT));
ASSERT (Context);
Context->MenuOption = CON_MENU_CONSOLE;
// Context->Handle = Handles[Index];
Context->DevicePath = DuplicateDevicePathInstance(DevicePathInst);
Context->DevicePathStr = DevicePathToStr (Context->DevicePath);
Context->ActiveConsole = MatchDevicePaths (PrevSelDevicePath, Context->DevicePath);
Attribute = CON_UNSELECTED;
Context->IsConIn = MatchDevicePaths (InpDevicePath, Context->DevicePath);
Context->IsConOut = MatchDevicePaths (OutDevicePath, Context->DevicePath);
Context->IsStdErr = MatchDevicePaths (ErrDevicePath, Context->DevicePath);
SPrint (Buffer, sizeof(Buffer), L" %s", Context->DevicePathStr);
Context->Menu = AllocateMenuOption (&ConsoleMenu, Buffer, Attribute, Context);
Context->Menu->ContextPrint = ConsoleContextPrint;
if (Context->ActiveConsole) {
ToggleSelectionStr(&ConsoleMenu,Context,Context->ActiveConsole);
//// Attribute = CON_SELECTED;
ActiveConsoleCount++;
}
}
AllocateSpecialMenuOption (&ConsoleMenu, L"Save Settings to NVRAM", CON_UNSELECTED, CON_MENU_SAVE_NVRAM);
AllocateSpecialMenuOption (&ConsoleMenu, L"Exit", CON_UNSELECTED, CON_MENU_EXIT);
ConsoleMenu.Header = Header;
ConsoleMenu.Footer = Footer;
ConsoleMenu.Selection = NULL;
NVRAMNeedsUpdating = FALSE;
for (Done = FALSE, ResultContext = NULL; !Done;) {
PreviousResultContext = ResultContext;
ResultContext = MenuDisplay (&ConsoleMenu, &Key);
if (!ResultContext) {
Done = TRUE;
break;
}
MenuOption = ResultContext->MenuOption;
if (MenuOption == CON_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 = CON_MENU_SAVE_NVRAM;
}
}
Done = TRUE;
}
switch (MenuOption) {
case CON_MENU_EXIT:
break;
case CON_MENU_SAVE_NVRAM:
Status = SetNvramForConsoleMenu (&ConsoleMenu, VarString, MenuType);
if (EFI_ERROR(Status)) {
PrintAt (ResultContext->Menu->Col, ResultContext->Menu->Row + 3, L"NVRAM update failed");
} else {
NVRAMNeedsUpdating = FALSE;
}
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?