fixes for IPF, CTRL-C support, and file redirection.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11066 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
477
ShellPkg/Application/Shell/ConsoleWrappers.c
Normal file
477
ShellPkg/Application/Shell/ConsoleWrappers.c
Normal file
@ -0,0 +1,477 @@
|
||||
/** @file
|
||||
Function definitions for shell simple text in and out on top of file handles.
|
||||
|
||||
Copyright (c) 2010, 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 <Uefi.h>
|
||||
#include <ShellBase.h>
|
||||
|
||||
#include "ConsoleWrappers.h"
|
||||
#include "Shell.h"
|
||||
|
||||
typedef struct {
|
||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;
|
||||
SHELL_FILE_HANDLE FileHandle;
|
||||
EFI_HANDLE TheHandle;
|
||||
} SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
|
||||
|
||||
typedef struct {
|
||||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SimpleTextOut;
|
||||
SHELL_FILE_HANDLE FileHandle;
|
||||
EFI_HANDLE TheHandle;
|
||||
} 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
|
||||
)
|
||||
{
|
||||
UINT64 Position;
|
||||
UINT64 Size;
|
||||
//
|
||||
// Someone is waiting on the keystroke event, if there's
|
||||
// a key pending, signal the event
|
||||
//
|
||||
// Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL
|
||||
//
|
||||
ShellInfoObject.NewEfiShellProtocol->GetFilePosition(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Context)->FileHandle, &Position);
|
||||
ShellInfoObject.NewEfiShellProtocol->GetFileSize (((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Context)->FileHandle, &Size );
|
||||
if (Position < Size) {
|
||||
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[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 EFI_INPUT_KEY *Key
|
||||
)
|
||||
{
|
||||
UINTN Size;
|
||||
Size = sizeof(CHAR16);
|
||||
if (Key == NULL || This == NULL) {
|
||||
return (EFI_INVALID_PARAMETER);
|
||||
}
|
||||
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*
|
||||
EFIAPI
|
||||
CreateSimpleTextInOnFile(
|
||||
IN SHELL_FILE_HANDLE FileHandleToUse,
|
||||
IN EFI_HANDLE *HandleLocation
|
||||
)
|
||||
{
|
||||
SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ProtocolToReturn;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (HandleLocation == NULL || FileHandleToUse == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ProtocolToReturn = AllocateZeroPool(sizeof(SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL));
|
||||
if (ProtocolToReturn == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
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
|
||||
EFIAPI
|
||||
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
|
||||
)
|
||||
{
|
||||
return (EFI_UNSUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@retval NULL There was insufficient memory available.
|
||||
@return A pointer to the allocated protocol structure;
|
||||
**/
|
||||
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
|
||||
EFIAPI
|
||||
CreateSimpleTextOutOnFile(
|
||||
IN SHELL_FILE_HANDLE FileHandleToUse,
|
||||
IN EFI_HANDLE *HandleLocation
|
||||
)
|
||||
{
|
||||
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->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 = 0;
|
||||
ProtocolToReturn->SimpleTextOut.Mode->Mode = 0;
|
||||
ProtocolToReturn->SimpleTextOut.Mode->Attribute = 0;
|
||||
ProtocolToReturn->SimpleTextOut.Mode->CursorColumn = 0;
|
||||
ProtocolToReturn->SimpleTextOut.Mode->CursorRow = 0;
|
||||
ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = FALSE;
|
||||
|
||||
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 {
|
||||
FreePool(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
|
||||
EFIAPI
|
||||
CloseSimpleTextOutOnFile(
|
||||
OUT 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);
|
||||
return (Status);
|
||||
}
|
Reference in New Issue
Block a user