terminal.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,176 行 · 第 1/3 页
C
1,176 行
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
if (TerminalDevice->ControllerNameTable) {
EfiLibFreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
}
Status = gBS->OpenProtocol (
ChildHandleBuffer[Index],
&gEfiHotPlugDeviceGuid,
NULL,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index],
&gEfiHotPlugDeviceGuid, NULL,
NULL
);
} else {
Status = EFI_SUCCESS;
}
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
gBS->FreePool (TerminalDevice);
}
}
if (EFI_ERROR(Status)) {
AllChildrenStopped = FALSE;
}
}
if (!AllChildrenStopped) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
VOID
TerminalUpdateConsoleDevVariable (
IN CHAR16 *VariableName,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath
)
{
EFI_STATUS Status;
UINTN VariableSize;
UINT8 TerminalType;
EFI_DEVICE_PATH_PROTOCOL *Variable;
EFI_DEVICE_PATH_PROTOCOL *NewVariable;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
Variable = NULL;
//
// Get global variable and its size according to the name given.
//
Variable = TerminalGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&VariableSize
);
//
// Append terminal device path onto the variable.
//
for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {
SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);
NewVariable = EfiAppendDevicePathInstance (Variable, TempDevicePath);
if (Variable != NULL) {
gBS->FreePool (Variable);
}
if (TempDevicePath != NULL) {
gBS->FreePool (TempDevicePath);
}
Variable = NewVariable;
}
VariableSize = EfiDevicePathSize (Variable);
Status = gRT->SetVariable (
VariableName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
VariableSize,
Variable
);
}
VOID
TerminalRemoveConsoleDevVariable (
IN CHAR16 *VariableName,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath
)
{
EFI_STATUS Status;
BOOLEAN FoundOne;
BOOLEAN Match;
UINTN VariableSize;
UINTN InstanceSize;
UINT8 TerminalType;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *Variable;
EFI_DEVICE_PATH_PROTOCOL *OriginalVariable;
EFI_DEVICE_PATH_PROTOCOL *NewVariable;
EFI_DEVICE_PATH_PROTOCOL *SavedNewVariable;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
Variable = NULL;
Instance = NULL;
//
// Get global variable and its size according to the name given.
//
Variable = TerminalGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&VariableSize
);
if (Variable == NULL) {
return;
}
FoundOne = FALSE;
OriginalVariable = Variable;
NewVariable = NULL;
//
// Get first device path instance from Variable
//
Instance = EfiDevicePathInstance (&Variable, &InstanceSize);
if (Instance == NULL) {
gBS->FreePool (OriginalVariable);
return;
}
//
// Loop through all the device path instances of Variable
//
do {
//
// Loop through all the terminal types that this driver supports
//
Match = FALSE;
for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type;
TerminalType++) {
SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);
//
// Compare the genterated device path to the current device path instance
//
if (TempDevicePath != NULL) {
if (EfiCompareMem (Instance, TempDevicePath, InstanceSize) == 0) {
Match = TRUE;
FoundOne = TRUE;
}
gBS->FreePool (TempDevicePath);
}
}
//
// If a match was not found, then keep the current device path instance
//
if (!Match) {
SavedNewVariable = NewVariable;
NewVariable = EfiAppendDevicePathInstance (NewVariable, Instance);
if (SavedNewVariable != NULL) {
gBS->FreePool (SavedNewVariable);
}
}
//
// Get next device path instance from Variable
//
gBS->FreePool(Instance);
Instance = EfiDevicePathInstance (&Variable, &InstanceSize);
} while (Instance != NULL);
gBS->FreePool (OriginalVariable);
if (FoundOne) {
VariableSize = EfiDevicePathSize (NewVariable);
Status = gRT->SetVariable (
VariableName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
VariableSize,
NewVariable
);
}
}
VOID *
TerminalGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
/*++
Routine Description:
Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
buffer, and the size of the buffer. On failure return NULL.
Arguments:
Name - String part of EFI variable name
VendorGuid - GUID part of EFI variable name
VariableSize - Returns the size of the EFI variable that was read
Returns:
Dynamically allocated memory that contains a copy of the EFI variable.
Caller is repsoncible freeing the buffer.
NULL - Variable was not read
--*/
{
EFI_STATUS Status;
UINTN BufferSize;
VOID *Buffer;
Buffer = NULL;
//
// Pass in a small size buffer to find the actual variable size.
//
BufferSize = 1;
Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer);
if (EFI_ERROR(Status)) {
*VariableSize = 0;
return NULL;
}
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (Status == EFI_SUCCESS) {
*VariableSize = BufferSize;
return Buffer;
} else if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate the buffer to return
//
gBS->FreePool (Buffer);
Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer);
if (EFI_ERROR (Status)) {
*VariableSize = 0;
return NULL;
}
//
// Read variable into the allocated buffer.
//
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (EFI_ERROR (Status)) {
BufferSize = 0;
gBS->FreePool (Buffer);
Buffer = NULL;
}
} else {
//
// Variable not found or other errors met.
//
BufferSize = 0 ;
gBS->FreePool (Buffer);
Buffer = NULL;
}
*VariableSize = BufferSize;
return Buffer;
}
EFI_STATUS
SetTerminalDevicePath (
IN UINT8 TerminalType,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
OUT EFI_DEVICE_PATH_PROTOCOL **TerminalDevicePath
)
{
VENDOR_DEVICE_PATH Node;
*TerminalDevicePath = NULL;
Node.Header.Type = MESSAGING_DEVICE_PATH;
Node.Header.SubType = MSG_VENDOR_DP;
//
// generate terminal device path node according to terminal type.
//
switch (TerminalType) {
case PcAnsiType:
EfiCopyMem (
&Node.Guid,
&gEfiPcAnsiGuid,
sizeof(EFI_GUID)
);
break;
case VT100Type:
EfiCopyMem (
&Node.Guid,
&gEfiVT100Guid,
sizeof(EFI_GUID)
);
break;
case VT100PlusType:
EfiCopyMem (
&Node.Guid,
&gEfiVT100PlusGuid,
sizeof(EFI_GUID)
);
break;
case VTUTF8Type:
EfiCopyMem (
&Node.Guid,
&gEfiVTUTF8Guid,
sizeof(EFI_GUID)
);
break;
default:
return EFI_UNSUPPORTED;
break;
}
SetDevicePathNodeLength (
&Node.Header,
sizeof(VENDOR_DEVICE_PATH)
);
//
// append the terminal node onto parent device path
// to generate a complete terminal device path.
//
*TerminalDevicePath = EfiAppendDevicePathNode (
ParentDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *)&Node
);
if (*TerminalDevicePath == NULL) {
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS;
}
VOID
InitializeRawFiFo (
IN TERMINAL_DEV *TerminalDevice
)
{
//
// Make the raw fifo empty.
//
TerminalDevice->RawFiFo.Head = TerminalDevice->RawFiFo.Tail;
}
VOID
InitializeUnicodeFiFo (
IN TERMINAL_DEV *TerminalDevice
)
{
//
// Make the unicode fifo empty
//
TerminalDevice->UnicodeFiFo.Head = TerminalDevice->UnicodeFiFo.Tail;
}
VOID
InitializeEfiKeyFiFo (
IN TERMINAL_DEV *TerminalDevice
)
{
//
// Make the efi key fifo empty
//
TerminalDevice->EfiKeyFiFo.Head = TerminalDevice->EfiKeyFiFo.Tail;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?