From 9ed21946c76e430097e9c4e59b419af928e0cb8c Mon Sep 17 00:00:00 2001 From: jaben carsey Date: Mon, 8 Feb 2016 15:59:04 -0800 Subject: 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 reviewed-by: Jaben Carsey --- ShellPkg/Application/Shell/FileHandleWrappers.c | 46 ++++++++++++++++--------- 1 file changed, 30 insertions(+), 16 deletions(-) (limited to 'ShellPkg/Application') 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.
(C) Copyright 2013 Hewlett-Packard Development Company, L.P.
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); } -- cgit v1.2.3