mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-30 12:43:41 +01:00
7c0aa811ec
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
515 lines
17 KiB
C
515 lines
17 KiB
C
/** @file
|
|
Function definitions for shell simple text in and out on top of file handles.
|
|
|
|
(C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
|
|
Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include "Shell.h"
|
|
|
|
extern BOOLEAN AsciiRedirection;
|
|
|
|
typedef struct {
|
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;
|
|
SHELL_FILE_HANDLE FileHandle;
|
|
EFI_HANDLE TheHandle;
|
|
UINT64 RemainingBytesOfInputFile;
|
|
} SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
|
|
|
|
typedef struct {
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SimpleTextOut;
|
|
SHELL_FILE_HANDLE FileHandle;
|
|
EFI_HANDLE TheHandle;
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalSimpleTextOut;
|
|
} SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
|
|
|
|
/**
|
|
Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
|
|
Signal the event if there is key available
|
|
|
|
@param Event Indicates the event that invoke this function.
|
|
@param Context Indicates the calling context.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
ConInWaitForKey (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
gBS->SignalEvent (Event);
|
|
}
|
|
|
|
/**
|
|
Reset function for the fake simple text input.
|
|
|
|
@param[in] This A pointer to the SimpleTextIn structure.
|
|
@param[in] ExtendedVerification TRUE for extra validation, FALSE otherwise.
|
|
|
|
@retval EFI_SUCCESS The reset was successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextInReset(
|
|
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
|
|
IN BOOLEAN ExtendedVerification
|
|
)
|
|
{
|
|
return (EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
ReadKeyStroke function for the fake simple text input.
|
|
|
|
@param[in] This A pointer to the SimpleTextIn structure.
|
|
@param[in, out] Key A pointer to the Key structure to fill.
|
|
|
|
@retval EFI_SUCCESS The read was successful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextInReadKeyStroke(
|
|
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
|
|
IN OUT EFI_INPUT_KEY *Key
|
|
)
|
|
{
|
|
UINTN Size;
|
|
UINTN CharSize;
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (Key == NULL || This == NULL) {
|
|
return (EFI_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// Check if we have any characters left in the stream.
|
|
//
|
|
if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile == 0) {
|
|
return (EFI_NOT_READY);
|
|
}
|
|
|
|
Size = sizeof(CHAR16);
|
|
|
|
if(!AsciiRedirection) {
|
|
CharSize = sizeof(CHAR16);
|
|
} else {
|
|
CharSize = sizeof(CHAR8);
|
|
}
|
|
//
|
|
// Decrement the amount of free space by Size or set to zero (for odd length files)
|
|
//
|
|
if (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile > CharSize) {
|
|
((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile -= CharSize;
|
|
} else {
|
|
((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->RemainingBytesOfInputFile = 0;
|
|
}
|
|
|
|
Key->ScanCode = 0;
|
|
return (ShellInfoObject.NewEfiShellProtocol->ReadFile(
|
|
((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)This)->FileHandle,
|
|
&Size,
|
|
&Key->UnicodeChar));
|
|
}
|
|
|
|
/**
|
|
Function to create a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
|
|
SHELL_FILE_HANDLE to support redirecting input from a file.
|
|
|
|
@param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
|
|
@param[in] HandleLocation The pointer of a location to copy handle with protocol to.
|
|
|
|
@retval NULL There was insufficient memory available.
|
|
@return A pointer to the allocated protocol structure;
|
|
**/
|
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL*
|
|
CreateSimpleTextInOnFile(
|
|
IN SHELL_FILE_HANDLE FileHandleToUse,
|
|
IN EFI_HANDLE *HandleLocation
|
|
)
|
|
{
|
|
SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ProtocolToReturn;
|
|
EFI_STATUS Status;
|
|
UINT64 CurrentPosition;
|
|
UINT64 FileSize;
|
|
|
|
if (HandleLocation == NULL || FileHandleToUse == NULL) {
|
|
return (NULL);
|
|
}
|
|
|
|
ProtocolToReturn = AllocateZeroPool(sizeof(SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL));
|
|
if (ProtocolToReturn == NULL) {
|
|
return (NULL);
|
|
}
|
|
|
|
ShellGetFileSize (FileHandleToUse, &FileSize);
|
|
ShellGetFilePosition(FileHandleToUse, &CurrentPosition);
|
|
|
|
//
|
|
// Initialize the protocol members
|
|
//
|
|
ProtocolToReturn->RemainingBytesOfInputFile = FileSize - CurrentPosition;
|
|
ProtocolToReturn->FileHandle = FileHandleToUse;
|
|
ProtocolToReturn->SimpleTextIn.Reset = FileBasedSimpleTextInReset;
|
|
ProtocolToReturn->SimpleTextIn.ReadKeyStroke = FileBasedSimpleTextInReadKeyStroke;
|
|
|
|
Status = gBS->CreateEvent (
|
|
EVT_NOTIFY_WAIT,
|
|
TPL_NOTIFY,
|
|
ConInWaitForKey,
|
|
&ProtocolToReturn->SimpleTextIn,
|
|
&ProtocolToReturn->SimpleTextIn.WaitForKey
|
|
);
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool(ProtocolToReturn);
|
|
return (NULL);
|
|
}
|
|
///@todo possibly also install SimpleTextInputEx on the handle at this point.
|
|
Status = gBS->InstallProtocolInterface(
|
|
&(ProtocolToReturn->TheHandle),
|
|
&gEfiSimpleTextInProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&(ProtocolToReturn->SimpleTextIn));
|
|
if (!EFI_ERROR(Status)) {
|
|
*HandleLocation = ProtocolToReturn->TheHandle;
|
|
return ((EFI_SIMPLE_TEXT_INPUT_PROTOCOL*)ProtocolToReturn);
|
|
} else {
|
|
FreePool(ProtocolToReturn);
|
|
return (NULL);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Function to close a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
|
|
SHELL_FILE_HANDLE to support redirecting input from a file.
|
|
|
|
@param[in] SimpleTextIn The pointer to the SimpleTextIn to close.
|
|
|
|
@retval EFI_SUCCESS The object was closed.
|
|
**/
|
|
EFI_STATUS
|
|
CloseSimpleTextInOnFile(
|
|
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextIn
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS Status1;
|
|
|
|
if (SimpleTextIn == NULL) {
|
|
return (EFI_INVALID_PARAMETER);
|
|
}
|
|
|
|
Status = gBS->CloseEvent(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)SimpleTextIn)->SimpleTextIn.WaitForKey);
|
|
|
|
Status1 = gBS->UninstallProtocolInterface(
|
|
((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL*)SimpleTextIn)->TheHandle,
|
|
&gEfiSimpleTextInProtocolGuid,
|
|
&(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL*)SimpleTextIn)->SimpleTextIn));
|
|
|
|
FreePool(SimpleTextIn);
|
|
if (!EFI_ERROR(Status)) {
|
|
return (Status1);
|
|
} else {
|
|
return (Status);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Reset the text output device hardware and optionaly run diagnostics.
|
|
|
|
@param This pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
|
|
@param ExtendedVerification Indicates that a more extensive test may be performed
|
|
|
|
@retval EFI_SUCCESS The text output device was reset.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutReset (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN BOOLEAN ExtendedVerification
|
|
)
|
|
{
|
|
return (EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
Verifies that all characters in a Unicode string can be output to the
|
|
target device.
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] WString The NULL-terminated Unicode string to be examined.
|
|
|
|
@retval EFI_SUCCESS The device(s) are capable of rendering the output string.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutTestString (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN CHAR16 *WString
|
|
)
|
|
{
|
|
return (EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
Returns information for an available text mode that the output device(s)
|
|
supports.
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] ModeNumber The mode number to return information on.
|
|
@param[out] Columns Upon return, the number of columns in the selected geometry
|
|
@param[out] Rows Upon return, the number of rows in the selected geometry
|
|
|
|
@retval EFI_UNSUPPORTED The mode number was not valid.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutQueryMode (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN ModeNumber,
|
|
OUT UINTN *Columns,
|
|
OUT UINTN *Rows
|
|
)
|
|
{
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *PassThruProtocol;
|
|
|
|
PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;
|
|
|
|
// Pass the QueryMode call thru to the original SimpleTextOutProtocol
|
|
return (PassThruProtocol->QueryMode(
|
|
PassThruProtocol,
|
|
ModeNumber,
|
|
Columns,
|
|
Rows));
|
|
}
|
|
|
|
/**
|
|
Sets the output device(s) to a specified mode.
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] ModeNumber The mode number to set.
|
|
|
|
@retval EFI_UNSUPPORTED The mode number was not valid.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutSetMode (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN ModeNumber
|
|
)
|
|
{
|
|
return (EFI_UNSUPPORTED);
|
|
}
|
|
|
|
/**
|
|
Sets the background and foreground colors for the OutputString () and
|
|
ClearScreen () functions.
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] Attribute The attribute to set. Bits 0..3 are the foreground color, and
|
|
bits 4..6 are the background color. All other bits are undefined
|
|
and must be zero. The valid Attributes are defined in this file.
|
|
|
|
@retval EFI_SUCCESS The attribute was set.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutSetAttribute (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN Attribute
|
|
)
|
|
{
|
|
return (EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
Clears the output device(s) display to the currently selected background
|
|
color.
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
|
|
@retval EFI_UNSUPPORTED The output device is not in a valid text mode.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutClearScreen (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
|
|
)
|
|
{
|
|
return (EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
Sets the current coordinates of the cursor position
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] Column Column to put the cursor in. Must be between zero and Column returned from QueryMode
|
|
@param[in] Row Row to put the cursor in. Must be between zero and Row returned from QueryMode
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutSetCursorPosition (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN Column,
|
|
IN UINTN Row
|
|
)
|
|
{
|
|
return (EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
Makes the cursor visible or invisible
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is
|
|
set to be invisible.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutEnableCursor (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN BOOLEAN Visible
|
|
)
|
|
{
|
|
return (EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
Write a Unicode string to the output device.
|
|
|
|
@param[in] This Protocol instance pointer.
|
|
@param[in] WString The NULL-terminated Unicode string to be displayed on the output
|
|
device(s). All output devices must also support the Unicode
|
|
drawing defined in this file.
|
|
@retval EFI_SUCCESS The string was output to the device.
|
|
@retval EFI_DEVICE_ERROR The device reported an error while attempting to output
|
|
the text.
|
|
@retval EFI_UNSUPPORTED The output device's mode is not currently in a
|
|
defined text mode.
|
|
@retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the
|
|
characters in the Unicode string could not be
|
|
rendered and were skipped.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FileBasedSimpleTextOutOutputString (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN CHAR16 *WString
|
|
)
|
|
{
|
|
UINTN Size;
|
|
Size = StrLen(WString) * sizeof(CHAR16);
|
|
return (ShellInfoObject.NewEfiShellProtocol->WriteFile(
|
|
((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->FileHandle,
|
|
&Size,
|
|
WString));
|
|
}
|
|
|
|
/**
|
|
Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
|
|
SHELL_FILE_HANDLE to support redirecting output from a file.
|
|
|
|
@param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
|
|
@param[in] HandleLocation The pointer of a location to copy handle with protocol to.
|
|
@param[in] OriginalProtocol The pointer to the original output protocol for pass thru of functions.
|
|
|
|
@retval NULL There was insufficient memory available.
|
|
@return A pointer to the allocated protocol structure;
|
|
**/
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
|
|
CreateSimpleTextOutOnFile(
|
|
IN SHELL_FILE_HANDLE FileHandleToUse,
|
|
IN EFI_HANDLE *HandleLocation,
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalProtocol
|
|
)
|
|
{
|
|
SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ProtocolToReturn;
|
|
EFI_STATUS Status;
|
|
|
|
if (HandleLocation == NULL || FileHandleToUse == NULL) {
|
|
return (NULL);
|
|
}
|
|
|
|
ProtocolToReturn = AllocateZeroPool(sizeof(SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL));
|
|
if (ProtocolToReturn == NULL) {
|
|
return (NULL);
|
|
}
|
|
ProtocolToReturn->FileHandle = FileHandleToUse;
|
|
ProtocolToReturn->OriginalSimpleTextOut = OriginalProtocol;
|
|
ProtocolToReturn->SimpleTextOut.Reset = FileBasedSimpleTextOutReset;
|
|
ProtocolToReturn->SimpleTextOut.TestString = FileBasedSimpleTextOutTestString;
|
|
ProtocolToReturn->SimpleTextOut.QueryMode = FileBasedSimpleTextOutQueryMode;
|
|
ProtocolToReturn->SimpleTextOut.SetMode = FileBasedSimpleTextOutSetMode;
|
|
ProtocolToReturn->SimpleTextOut.SetAttribute = FileBasedSimpleTextOutSetAttribute;
|
|
ProtocolToReturn->SimpleTextOut.ClearScreen = FileBasedSimpleTextOutClearScreen;
|
|
ProtocolToReturn->SimpleTextOut.SetCursorPosition = FileBasedSimpleTextOutSetCursorPosition;
|
|
ProtocolToReturn->SimpleTextOut.EnableCursor = FileBasedSimpleTextOutEnableCursor;
|
|
ProtocolToReturn->SimpleTextOut.OutputString = FileBasedSimpleTextOutOutputString;
|
|
ProtocolToReturn->SimpleTextOut.Mode = AllocateZeroPool(sizeof(EFI_SIMPLE_TEXT_OUTPUT_MODE));
|
|
if (ProtocolToReturn->SimpleTextOut.Mode == NULL) {
|
|
FreePool(ProtocolToReturn);
|
|
return (NULL);
|
|
}
|
|
ProtocolToReturn->SimpleTextOut.Mode->MaxMode = OriginalProtocol->Mode->MaxMode;
|
|
ProtocolToReturn->SimpleTextOut.Mode->Mode = OriginalProtocol->Mode->Mode;
|
|
ProtocolToReturn->SimpleTextOut.Mode->Attribute = OriginalProtocol->Mode->Attribute;
|
|
ProtocolToReturn->SimpleTextOut.Mode->CursorColumn = OriginalProtocol->Mode->CursorColumn;
|
|
ProtocolToReturn->SimpleTextOut.Mode->CursorRow = OriginalProtocol->Mode->CursorRow;
|
|
ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = OriginalProtocol->Mode->CursorVisible;
|
|
|
|
Status = gBS->InstallProtocolInterface(
|
|
&(ProtocolToReturn->TheHandle),
|
|
&gEfiSimpleTextOutProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&(ProtocolToReturn->SimpleTextOut));
|
|
if (!EFI_ERROR(Status)) {
|
|
*HandleLocation = ProtocolToReturn->TheHandle;
|
|
return ((EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)ProtocolToReturn);
|
|
} else {
|
|
SHELL_FREE_NON_NULL(ProtocolToReturn->SimpleTextOut.Mode);
|
|
SHELL_FREE_NON_NULL(ProtocolToReturn);
|
|
return (NULL);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Function to close a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
|
|
SHELL_FILE_HANDLE to support redirecting output from a file.
|
|
|
|
@param[in] SimpleTextOut The pointer to the SimpleTextOUT to close.
|
|
|
|
@retval EFI_SUCCESS The object was closed.
|
|
**/
|
|
EFI_STATUS
|
|
CloseSimpleTextOutOnFile(
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
if (SimpleTextOut == NULL) {
|
|
return (EFI_INVALID_PARAMETER);
|
|
}
|
|
Status = gBS->UninstallProtocolInterface(
|
|
((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->TheHandle,
|
|
&gEfiSimpleTextOutProtocolGuid,
|
|
&(((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->SimpleTextOut));
|
|
FreePool(SimpleTextOut->Mode);
|
|
FreePool(SimpleTextOut);
|
|
return (Status);
|
|
}
|