summaryrefslogtreecommitdiffstats
path: root/ShellPkg
diff options
context:
space:
mode:
authorjaben carsey <jaben.carsey@intel.com>2016-02-08 15:59:04 -0800
committerjaben carsey <jaben.carsey@intel.com>2016-02-08 15:59:04 -0800
commitd2a0d2e6acea4d6a3dbe31b68a9a7fe7511cb478 (patch)
tree67340a2df1d655746d350cdc9fc4672f092e90a6 /ShellPkg
parent8de84d4242215252af9d2afecd45e2419689ee5f (diff)
downloadedk2-d2a0d2e6acea4d6a3dbe31b68a9a7fe7511cb478.tar.gz
edk2-d2a0d2e6acea4d6a3dbe31b68a9a7fe7511cb478.tar.bz2
edk2-d2a0d2e6acea4d6a3dbe31b68a9a7fe7511cb478.zip
ShellPkg: Fix ASCII and UNICODE file pipes.
Fix various errors when piping a UNICODE or ASCII file to a simple shell application that reads standard input and writes it to standard output. 1) When the memory file is created by CreateFileInferfaceMem() to capture the pipe output, no UNICODE BOM is written to the memory file. Later, when the memory file is read by the application using ShellFileHandleReadLine(), the function indicates that the file is ASCII because there is no BOM. 2) If the file is piped as ASCII, the ASCII memory image is not correctly created by FileInterfaceMemWrite() as each ASCII character is followed by '\0' in the image (when the ASCII data is written to the memory image, the file position should only be incremented by half the buffer size). 3) ShellFileHandleReadLine() does not read ASCII files correctly (writes to Buffer need to be cast as CHAR8*). 4) FileInterfaceMemRead() and FileInterfaceMemWrite() as somewhat hard to read and difficult to debug with certain tools due to the typecasting of This. Added a local variable (MemFile) of the correct type to these functions and used it instead of This. Enhancement: ShellFileHandleReadLine() now returns EFI_END_OF_FILE when appropriate. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jim Dailey <jim_dailey@dell.com> reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
Diffstat (limited to 'ShellPkg')
-rw-r--r--ShellPkg/Application/Shell/FileHandleWrappers.c46
-rw-r--r--ShellPkg/Include/Library/ShellLib.h1
-rw-r--r--ShellPkg/Library/UefiShellLib/UefiShellLib.c57
-rw-r--r--ShellPkg/Library/UefiShellLib/UefiShellLib.inf2
4 files changed, 71 insertions, 35 deletions
diff --git a/ShellPkg/Application/Shell/FileHandleWrappers.c b/ShellPkg/Application/Shell/FileHandleWrappers.c
index 64f382718b..168b78bd25 100644
--- a/ShellPkg/Application/Shell/FileHandleWrappers.c
+++ b/ShellPkg/Application/Shell/FileHandleWrappers.c
@@ -2,6 +2,7 @@
EFI_FILE_PROTOCOL wrappers for other items (Like Environment Variables,
StdIn, StdOut, StdErr, etc...).
+ Copyright 2016 Dell Inc.
Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
This program and the accompanying materials
@@ -1385,17 +1386,20 @@ FileInterfaceMemWrite(
IN VOID *Buffer
)
{
- CHAR8 *AsciiBuffer;
- if (((EFI_FILE_PROTOCOL_MEM*)This)->Unicode) {
+ CHAR8 *AsciiBuffer;
+ EFI_FILE_PROTOCOL_MEM *MemFile;
+
+ MemFile = (EFI_FILE_PROTOCOL_MEM *) This;
+ if (MemFile->Unicode) {
//
// Unicode
//
- if ((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position + (*BufferSize)) > (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize)) {
- ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer = ReallocatePool((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize), (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) + (*BufferSize) + 10, ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer);
- ((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize += (*BufferSize) + 10;
+ if ((UINTN)(MemFile->Position + (*BufferSize)) > (UINTN)(MemFile->BufferSize)) {
+ MemFile->Buffer = ReallocatePool((UINTN)(MemFile->BufferSize), (UINTN)(MemFile->BufferSize) + (*BufferSize) + 10, MemFile->Buffer);
+ MemFile->BufferSize += (*BufferSize) + 10;
}
- CopyMem(((UINT8*)((EFI_FILE_PROTOCOL_MEM*)This)->Buffer) + ((EFI_FILE_PROTOCOL_MEM*)This)->Position, Buffer, *BufferSize);
- ((EFI_FILE_PROTOCOL_MEM*)This)->Position += (*BufferSize);
+ CopyMem(((UINT8*)MemFile->Buffer) + MemFile->Position, Buffer, *BufferSize);
+ MemFile->Position += (*BufferSize);
return (EFI_SUCCESS);
} else {
//
@@ -1406,12 +1410,12 @@ FileInterfaceMemWrite(
return (EFI_OUT_OF_RESOURCES);
}
AsciiSPrint(AsciiBuffer, *BufferSize, "%S", Buffer);
- if ((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position + AsciiStrSize(AsciiBuffer)) > (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize)) {
- ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer = ReallocatePool((UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize), (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) + AsciiStrSize(AsciiBuffer) + 10, ((EFI_FILE_PROTOCOL_MEM*)This)->Buffer);
- ((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize += AsciiStrSize(AsciiBuffer) + 10;
+ if ((UINTN)(MemFile->Position + AsciiStrSize(AsciiBuffer)) > (UINTN)(MemFile->BufferSize)) {
+ MemFile->Buffer = ReallocatePool((UINTN)(MemFile->BufferSize), (UINTN)(MemFile->BufferSize) + AsciiStrSize(AsciiBuffer) + 10, MemFile->Buffer);
+ MemFile->BufferSize += AsciiStrSize(AsciiBuffer) + 10;
}
- CopyMem(((UINT8*)((EFI_FILE_PROTOCOL_MEM*)This)->Buffer) + ((EFI_FILE_PROTOCOL_MEM*)This)->Position, AsciiBuffer, AsciiStrSize(AsciiBuffer));
- ((EFI_FILE_PROTOCOL_MEM*)This)->Position += AsciiStrSize(AsciiBuffer);
+ CopyMem(((UINT8*)MemFile->Buffer) + MemFile->Position, AsciiBuffer, AsciiStrSize(AsciiBuffer));
+ MemFile->Position += (*BufferSize / sizeof(CHAR16));
FreePool(AsciiBuffer);
return (EFI_SUCCESS);
}
@@ -1434,11 +1438,14 @@ FileInterfaceMemRead(
IN VOID *Buffer
)
{
- if (*BufferSize > (UINTN)((((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) - (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position))) {
- (*BufferSize) = (UINTN)((((EFI_FILE_PROTOCOL_MEM*)This)->BufferSize) - (UINTN)(((EFI_FILE_PROTOCOL_MEM*)This)->Position));
+ EFI_FILE_PROTOCOL_MEM *MemFile;
+
+ MemFile = (EFI_FILE_PROTOCOL_MEM *) This;
+ if (*BufferSize > (UINTN)((MemFile->BufferSize) - (UINTN)(MemFile->Position))) {
+ (*BufferSize) = (UINTN)((MemFile->BufferSize) - (UINTN)(MemFile->Position));
}
- CopyMem(Buffer, ((UINT8*)((EFI_FILE_PROTOCOL_MEM*)This)->Buffer) + ((EFI_FILE_PROTOCOL_MEM*)This)->Position, (*BufferSize));
- ((EFI_FILE_PROTOCOL_MEM*)This)->Position = ((EFI_FILE_PROTOCOL_MEM*)This)->Position + (*BufferSize);
+ CopyMem(Buffer, ((UINT8*)MemFile->Buffer) + MemFile->Position, (*BufferSize));
+ MemFile->Position = MemFile->Position + (*BufferSize);
return (EFI_SUCCESS);
}
@@ -1507,6 +1514,13 @@ CreateFileInterfaceMem(
ASSERT(FileInterface->BufferSize == 0);
ASSERT(FileInterface->Position == 0);
+ if (Unicode) {
+ FileInterface->Buffer = AllocateZeroPool(sizeof(gUnicodeFileTag));
+ *((CHAR16 *) (FileInterface->Buffer)) = EFI_UNICODE_BYTE_ORDER_MARK;
+ FileInterface->BufferSize = 2;
+ FileInterface->Position = 2;
+ }
+
return ((EFI_FILE_PROTOCOL *)FileInterface);
}
diff --git a/ShellPkg/Include/Library/ShellLib.h b/ShellPkg/Include/Library/ShellLib.h
index d02d6e9de1..88020a06a8 100644
--- a/ShellPkg/Include/Library/ShellLib.h
+++ b/ShellPkg/Include/Library/ShellLib.h
@@ -1333,6 +1333,7 @@ ShellFileHandleReturnLine(
@retval EFI_SUCCESS The operation was successful. The line is stored in
Buffer.
+ @retval EFI_END_OF_FILE There are no more lines in the file.
@retval EFI_INVALID_PARAMETER Handle was NULL.
@retval EFI_INVALID_PARAMETER Size was NULL.
@retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
index 9e815c56a6..4b53c7080c 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
@@ -1,6 +1,7 @@
/** @file
Provides interface to shell functionality for shell commands and applications.
+ Copyright 2016 Dell Inc.
Copyright (c) 2006 - 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
@@ -4097,6 +4098,7 @@ ShellFileHandleReturnLine(
@retval EFI_SUCCESS The operation was successful. The line is stored in
Buffer.
+ @retval EFI_END_OF_FILE There are no more lines in the file.
@retval EFI_INVALID_PARAMETER Handle was NULL.
@retval EFI_INVALID_PARAMETER Size was NULL.
@retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line.
@@ -4142,45 +4144,64 @@ ShellFileHandleReadLine(
}
}
+ if (*Ascii) {
+ CharSize = sizeof(CHAR8);
+ } else {
+ CharSize = sizeof(CHAR16);
+ }
for (CountSoFar = 0;;CountSoFar++){
CharBuffer = 0;
- if (*Ascii) {
- CharSize = sizeof(CHAR8);
- } else {
- CharSize = sizeof(CHAR16);
- }
Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);
if ( EFI_ERROR(Status)
|| CharSize == 0
|| (CharBuffer == L'\n' && !(*Ascii))
|| (CharBuffer == '\n' && *Ascii)
){
+ if (CharSize == 0) {
+ Status = EFI_END_OF_FILE;
+ }
break;
}
//
// if we have space save it...
//
- if ((CountSoFar+1)*sizeof(CHAR16) < *Size){
+ if ((CountSoFar + 1) * CharSize < *Size){
ASSERT(Buffer != NULL);
- ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;
- ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;
+ if (*Ascii) {
+ ((CHAR8*)Buffer)[CountSoFar] = (CHAR8) CharBuffer;
+ ((CHAR8*)Buffer)[CountSoFar+1] = '\0';
+ }
+ else {
+ ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;
+ ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;
+ }
}
}
//
// if we ran out of space tell when...
//
- if ((CountSoFar+1)*sizeof(CHAR16) > *Size){
- *Size = (CountSoFar+1)*sizeof(CHAR16);
- if (!Truncate) {
- gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);
- } else {
- DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));
+ if (Status != EFI_END_OF_FILE){
+ if ((CountSoFar + 1) * CharSize > *Size){
+ *Size = (CountSoFar + 1) * CharSize;
+ if (!Truncate) {
+ gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);
+ } else {
+ DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));
+ }
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+
+ if (*Ascii) {
+ if (CountSoFar && ((CHAR8*)Buffer)[CountSoFar - 1] == '\r') {
+ ((CHAR8*)Buffer)[CountSoFar - 1] = '\0';
+ }
+ }
+ else {
+ if (CountSoFar && Buffer[CountSoFar - 1] == L'\r') {
+ Buffer[CountSoFar - 1] = CHAR_NULL;
+ }
}
- return (EFI_BUFFER_TOO_SMALL);
- }
- while(Buffer[StrLen(Buffer)-1] == L'\r') {
- Buffer[StrLen(Buffer)-1] = CHAR_NULL;
}
return (Status);
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.inf b/ShellPkg/Library/UefiShellLib/UefiShellLib.inf
index 6ed76cc2bc..d44ce02bb3 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.inf
@@ -18,7 +18,7 @@
BASE_NAME = UefiShellLib
FILE_GUID = 449D0F00-2148-4a43-9836-F10B3980ECF5
MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.0
+ VERSION_STRING = 1.1
LIBRARY_CLASS = ShellLib|UEFI_APPLICATION UEFI_DRIVER DXE_RUNTIME_DRIVER DXE_DRIVER
CONSTRUCTOR = ShellLibConstructor
DESTRUCTOR = ShellLibDestructor