X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ShellPkg%2FApplication%2FShell%2FConsoleWrappers.c;h=a0861e6a1d2390be7ab345a11ead4814ab1015c3;hb=ba0014b9f8ae1a593f03e744f26008214c2b06a8;hp=38491216f39a87635428ad23ed4dc73485683ad7;hpb=dcf9b428e66e2bc57b70e7e0289f07c72efbbb44;p=mirror_edk2.git
diff --git a/ShellPkg/Application/Shell/ConsoleWrappers.c b/ShellPkg/Application/Shell/ConsoleWrappers.c
index 38491216f3..a0861e6a1d 100644
--- a/ShellPkg/Application/Shell/ConsoleWrappers.c
+++ b/ShellPkg/Application/Shell/ConsoleWrappers.c
@@ -1,8 +1,8 @@
/** @file
Function definitions for shell simple text in and out on top of file handles.
- Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+ (C) Copyright 2013 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
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
@@ -15,10 +15,13 @@
#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 {
@@ -43,19 +46,7 @@ ConInWaitForKey (
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);
- }
+ gBS->SignalEvent (Event);
}
/**
@@ -92,10 +83,38 @@ FileBasedSimpleTextInReadKeyStroke(
)
{
UINTN Size;
- Size = sizeof(CHAR16);
+ 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,
@@ -104,7 +123,7 @@ FileBasedSimpleTextInReadKeyStroke(
}
/**
- Function to create a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
+ 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.
@@ -114,7 +133,6 @@ FileBasedSimpleTextInReadKeyStroke(
@return A pointer to the allocated protocol structure;
**/
EFI_SIMPLE_TEXT_INPUT_PROTOCOL*
-EFIAPI
CreateSimpleTextInOnFile(
IN SHELL_FILE_HANDLE FileHandleToUse,
IN EFI_HANDLE *HandleLocation
@@ -122,6 +140,8 @@ CreateSimpleTextInOnFile(
{
SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ProtocolToReturn;
EFI_STATUS Status;
+ UINT64 CurrentPosition;
+ UINT64 FileSize;
if (HandleLocation == NULL || FileHandleToUse == NULL) {
return (NULL);
@@ -131,10 +151,18 @@ CreateSimpleTextInOnFile(
if (ProtocolToReturn == NULL) {
return (NULL);
}
- ProtocolToReturn->FileHandle = FileHandleToUse;
+
+ 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,
@@ -149,9 +177,9 @@ CreateSimpleTextInOnFile(
}
///@todo possibly also install SimpleTextInputEx on the handle at this point.
Status = gBS->InstallProtocolInterface(
- &(ProtocolToReturn->TheHandle),
- &gEfiSimpleTextInProtocolGuid,
- EFI_NATIVE_INTERFACE,
+ &(ProtocolToReturn->TheHandle),
+ &gEfiSimpleTextInProtocolGuid,
+ EFI_NATIVE_INTERFACE,
&(ProtocolToReturn->SimpleTextIn));
if (!EFI_ERROR(Status)) {
*HandleLocation = ProtocolToReturn->TheHandle;
@@ -163,7 +191,7 @@ CreateSimpleTextInOnFile(
}
/**
- Function to close a EFI_SIMPLE_TEXT_INPUT_PROTOCOL on top of a
+ 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.
@@ -171,7 +199,6 @@ CreateSimpleTextInOnFile(
@retval EFI_SUCCESS The object was closed.
**/
EFI_STATUS
-EFIAPI
CloseSimpleTextInOnFile(
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextIn
)
@@ -186,8 +213,8 @@ CloseSimpleTextInOnFile(
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)->TheHandle,
+ &gEfiSimpleTextInProtocolGuid,
&(((SHELL_EFI_SIMPLE_TEXT_INPUT_PROTOCOL*)SimpleTextIn)->SimpleTextIn));
FreePool(SimpleTextIn);
@@ -255,8 +282,10 @@ FileBasedSimpleTextOutQueryMode (
OUT UINTN *Rows
)
{
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;
-
+ 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,
@@ -392,7 +421,7 @@ FileBasedSimpleTextOutOutputString (
}
/**
- Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
+ 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.
@@ -403,7 +432,6 @@ FileBasedSimpleTextOutOutputString (
@return A pointer to the allocated protocol structure;
**/
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
-EFIAPI
CreateSimpleTextOutOnFile(
IN SHELL_FILE_HANDLE FileHandleToUse,
IN EFI_HANDLE *HandleLocation,
@@ -445,21 +473,22 @@ CreateSimpleTextOutOnFile(
ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = OriginalProtocol->Mode->CursorVisible;
Status = gBS->InstallProtocolInterface(
- &(ProtocolToReturn->TheHandle),
- &gEfiSimpleTextOutProtocolGuid,
- EFI_NATIVE_INTERFACE,
+ &(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);
+ 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
+ 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.
@@ -467,7 +496,6 @@ CreateSimpleTextOutOnFile(
@retval EFI_SUCCESS The object was closed.
**/
EFI_STATUS
-EFIAPI
CloseSimpleTextOutOnFile(
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut
)
@@ -477,9 +505,10 @@ CloseSimpleTextOutOnFile(
return (EFI_INVALID_PARAMETER);
}
Status = gBS->UninstallProtocolInterface(
- ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->TheHandle,
- &gEfiSimpleTextOutProtocolGuid,
+ ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->TheHandle,
+ &gEfiSimpleTextOutProtocolGuid,
&(((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*)SimpleTextOut)->SimpleTextOut));
+ FreePool(SimpleTextOut->Mode);
FreePool(SimpleTextOut);
return (Status);
}