consplitter.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,473 行 · 第 1/5 页
C
2,473 行
);
gBS->CloseProtocol (
ControllerHandle,
DeviceGuid,
This->DriverBindingHandle,
ControllerHandle
);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
ConSplitterConInDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
(Standard DriverBinding Protocol Stop() function)
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn;
if (NumberOfChildren == 0) {
return EFI_SUCCESS;
}
Status = ConSplitterStop (
This,
ControllerHandle,
mConIn.VirtualHandle,
&gEfiConsoleInDeviceGuid,
&gEfiSimpleTextInProtocolGuid,
(VOID **)&TextIn
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Delete this console input device's data structures.
//
return ConSplitterTextInDeleteDevice (&mConIn, TextIn);
}
STATIC
EFI_STATUS
EFIAPI
ConSplitterSimplePointerDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
(Standard DriverBinding Protocol Stop() function)
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
if (NumberOfChildren == 0) {
return EFI_SUCCESS;
}
Status = ConSplitterStop (
This,
ControllerHandle,
mConIn.VirtualHandle,
&gEfiSimplePointerProtocolGuid,
&gEfiSimplePointerProtocolGuid,
(VOID **)&SimplePointer
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Delete this console input device's data structures.
//
return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer);
}
STATIC
EFI_STATUS
EFIAPI
ConSplitterConOutDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
(Standard DriverBinding Protocol Stop() function)
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
if (NumberOfChildren == 0) {
return EFI_SUCCESS;
}
Status = ConSplitterStop (
This,
ControllerHandle,
mConOut.VirtualHandle,
&gEfiConsoleOutDeviceGuid,
&gEfiSimpleTextOutProtocolGuid,
(VOID **)&TextOut
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Remove any UGA devices
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUgaDrawProtocolGuid,
&UgaDraw,
This->DriverBindingHandle,
mConOut.VirtualHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
//
// Delete this console output device's data structures.
//
return ConSplitterTextOutDeleteDevice (&mConOut, TextOut);
}
STATIC
EFI_STATUS
EFIAPI
ConSplitterStdErrDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
(Standard DriverBinding Protocol Stop() function)
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_SIMPLE_TEXT_OUT_PROTOCOL *TextOut;
if (NumberOfChildren == 0) {
return EFI_SUCCESS;
}
Status = ConSplitterStop (
This,
ControllerHandle,
mStdErr.VirtualHandle,
&gEfiStandardErrorDeviceGuid,
&gEfiSimpleTextOutProtocolGuid,
(VOID **)&TextOut
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Delete this console error out device's data structures.
//
Status = ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);
if (EFI_ERROR (Status)) {
return Status;
}
if (mStdErr.CurrentNumberOfConsoles == 0) {
gST->StandardErrorHandle = NULL;
gST->StdErr = NULL;
//
// Update the CRC32 in the EFI System Table header
//
gST->Hdr.CRC32 = 0;
gBS->CalculateCrc32 ((UINT8 *)&gST->Hdr,
gST->Hdr.HeaderSize,
&gST->Hdr.CRC32
);
}
return Status;
}
EFI_STATUS
ConSplitterGrowBuffer (
IN UINTN SizeOfCount,
IN UINTN *Count,
IN OUT VOID **Buffer
)
/*++
Routine Description:
Take the passed in Buffer of size SizeOfCount and grow the buffer
by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount
bytes. Copy the current data in Buffer to the new version of Buffer
and free the old version of buffer.
Arguments:
SizeOfCount - Size of element in array
Count - Current number of elements in array
Buffer - Bigger version of passed in Buffer with all the data
Returns:
EFI_SUCCESS - Buffer size has grown
EFI_OUT_OF_RESOURCES - Could not grow the buffer size
None
--*/
{
UINTN NewSize;
UINTN OldSize;
VOID *Ptr;
//
// grow the buffer to new buffer size,
// copy the old buffer's content to the new-size buffer,
// then free the old buffer.
//
OldSize = *Count * SizeOfCount;
*Count += CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT;
NewSize = *Count * SizeOfCount;
Ptr = EfiLibAllocateZeroPool (NewSize);
if ( Ptr == NULL ) {
return EFI_OUT_OF_RESOURCES;
}
EfiCopyMem (Ptr, *Buffer, OldSize);
if (*Buffer != NULL) {
gBS->FreePool (*Buffer);
}
*Buffer = Ptr;
return EFI_SUCCESS;
}
EFI_STATUS
ConSplitterTextInAddDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
//
// If the Text In List is full, enlarge it by calling growbuffer().
//
if ( Private->CurrentNumberOfConsoles >= Private->TextInListCount ) {
Status = ConSplitterGrowBuffer (
sizeof (EFI_SIMPLE_TEXT_IN_PROTOCOL *),
&Private->TextInListCount,
(VOID **)&Private->TextInList
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
}
//
// Add the new text-in device data structure into the Text In List.
//
Private->TextInList[Private->CurrentNumberOfConsoles] = TextIn;
Private->CurrentNumberOfConsoles++;
return EFI_SUCCESS;
}
EFI_STATUS
ConSplitterTextInDeleteDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *TextIn
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINTN Index;
//
// Remove the specified text-in device data structure from the Text In List,
// and rearrange the remaining data structures in the Text In List.
//
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
if (Private->TextInList[Index] == TextIn) {
for (Index = Index; Index < Private->CurrentNumberOfConsoles - 1;
Index++) {
Private->TextInList[Index] = Private->TextInList[Index + 1];
}
Private->CurrentNumberOfConsoles--;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
ConSplitterSimplePointerAddDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
//
// If the Text In List is full, enlarge it by calling growbuffer().
//
if (Private->CurrentNumberOfPointers >= Private->PointerListCount) {
Status = ConSplitterGrowBuffer (
sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),
&Private->PointerListCount,
(VOID **)&Private->PointerList
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
}
//
// Add the new text-in device data structure into the Text In List.
//
Private->PointerList[Private->CurrentNumberOfPointers] = SimplePointer;
Private->CurrentNumberOfPointers++;
return EFI_SUCCESS;
}
EFI_STATUS
ConSplitterSimplePointerDeleteDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINTN Index;
//
// Remove the specified text-in device data structure from the Text In List,
// and rearrange the remaining data structures in the Text In List.
//
for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {
if (Private->PointerList[Index] == SimplePointer) {
for (Index = Index; Index < Private->CurrentNumberOfPointers - 1;
Index++) {
Private->PointerList[Index] = Private->PointerList[Index + 1];
}
Private->CurrentNumberOfPointers--;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
ConSplitterGrowMapTable (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINTN Size, NewSize, TotalSize;
INT32 *TextOutModeMap, *OldTextOutModeMap;
INT32 *SrcAddress;
INT32 Index;
NewSize = Private->TextOutListCount * sizeof (INT32);
OldTextOutModeMap = Private->TextOutModeMap;
TotalSize = NewSize * Private->TextOutQueryDataCount;
TextOutModeMap = EfiLibAllocateZeroPool (TotalSize);
if ( TextOutModeMap == NULL ) {
return EFI_OUT_OF_RESOURCES;
}
EfiSetMem (TextOutModeMap, TotalSize, 0xFF);
Private->TextOutModeMap = TextOutModeMap;
//
// If TextOutList has been enlarged, need to realloc the mode map table
// The mode map table is regarded as a two dimension array.
//
// Old New
// 0 ---------> TextOutListCount ----> TextOutListCount
// | -------------------------------------------
// | | | |
// | | | |
// | | | |
// | | | |
// | | | |
// \/ | | |
// -------------------------------------------
// QueryDataCount
//
if ( OldTextOutModeMap ) {
Size = Private->CurrentNumberOfConsoles * sizeof (INT32);
Index = 0;
SrcAddress = OldTextOutModeMap;
//
// Copy the old data to the new one
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?