* [PATCH v1] ShellPkg/TftpDynamicCommand: Change file writing method in tftp
@ 2019-01-09 8:42 Songpeng Li
2019-01-10 1:27 ` Wu, Jiaxin
0 siblings, 1 reply; 2+ messages in thread
From: Songpeng Li @ 2019-01-09 8:42 UTC (permalink / raw)
To: edk2-devel; +Cc: Jaben Carsey, Ruiyu Ni, Wu Jiaxin
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1433
Current logic of shell tftp download was writing file after tftp
download finished, when the file is large, it looks like the shell
tftp command hanged after download was finished. To improve
end-user experience, the solution is using split file writing
instead.
This patch update the code to open and close file inside
DownloadFile(), and save each packet to file within callback
function CheckPacket().
Since AllocatePage() is no-longer needed, This patch can also
remove the memory limitation. The download file can be larger
than system free memory now.
Cc: Jaben Carsey <jaben.carsey@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Songpeng Li <songpeng.li@intel.com>
---
ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c | 152 +++++++++-----------
1 file changed, 64 insertions(+), 88 deletions(-)
diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
index ed081b5bad7c..a53fe16f0683 100644
--- a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
+++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
@@ -41,6 +41,12 @@ STATIC CONST CHAR16 mTftpProgressFrame[] = L"[
// (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'
STATIC CONST CHAR16 mTftpProgressDelete[] = L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
+// Local File Handle
+SHELL_FILE_HANDLE mFileHandle;
+
+// Path of the local file, Unicode encoded
+CONST CHAR16 *mLocalFilePath;
+
/**
Check and convert the UINT16 option values of the 'tftp' command
@@ -166,9 +172,6 @@ GetFileSize (
@param[in] FileSize Size of the file in number of bytes
@param[in] BlockSize Value of the TFTP blksize option
@param[in] WindowSize Value of the TFTP window size option
- @param[out] Data Address where to store the address of the buffer
- where the data of the file were downloaded in
- case of success.
@retval EFI_SUCCESS The file was downloaded.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
@@ -184,8 +187,7 @@ DownloadFile (
IN CONST CHAR8 *AsciiFilePath,
IN UINTN FileSize,
IN UINT16 BlockSize,
- IN UINT16 WindowSize,
- OUT VOID **Data
+ IN UINT16 WindowSize
);
/**
@@ -287,7 +289,6 @@ RunTftp (
CHAR8 *AsciiRemoteFilePath;
UINTN FilePathSize;
CONST CHAR16 *Walker;
- CONST CHAR16 *LocalFilePath;
EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData;
EFI_HANDLE *Handles;
UINTN HandleCount;
@@ -297,9 +298,7 @@ RunTftp (
EFI_HANDLE Mtftp4ChildHandle;
EFI_MTFTP4_PROTOCOL *Mtftp4;
UINTN FileSize;
- UINTN DataSize;
VOID *Data;
- SHELL_FILE_HANDLE FileHandle;
UINT16 BlockSize;
UINT16 WindowSize;
@@ -309,7 +308,6 @@ RunTftp (
AsciiRemoteFilePath = NULL;
Handles = NULL;
FileSize = 0;
- DataSize = 0;
BlockSize = MTFTP_DEFAULT_BLKSIZE;
WindowSize = MTFTP_DEFAULT_WINDOWSIZE;
@@ -385,7 +383,7 @@ RunTftp (
UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);
if (ParamCount == 4) {
- LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
+ mLocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
} else {
Walker = RemoteFilePath + StrLen (RemoteFilePath);
while ((--Walker) >= RemoteFilePath) {
@@ -394,7 +392,7 @@ RunTftp (
break;
}
}
- LocalFilePath = Walker + 1;
+ mLocalFilePath = Walker + 1;
}
//
@@ -543,7 +541,7 @@ RunTftp (
goto NextHandle;
}
- Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize, &Data);
+ Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize);
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (
-1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),
@@ -552,45 +550,8 @@ RunTftp (
goto NextHandle;
}
- DataSize = FileSize;
-
- if (!EFI_ERROR (ShellFileExists (LocalFilePath))) {
- ShellDeleteFileByName (LocalFilePath);
- }
-
- Status = ShellOpenFileByName (
- LocalFilePath,
- &FileHandle,
- EFI_FILE_MODE_CREATE |
- EFI_FILE_MODE_WRITE |
- EFI_FILE_MODE_READ,
- 0
- );
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
- mTftpHiiHandle, L"tftp", LocalFilePath
- );
- goto NextHandle;
- }
-
- Status = ShellWriteFile (FileHandle, &FileSize, Data);
- if (!EFI_ERROR (Status)) {
- ShellStatus = SHELL_SUCCESS;
- } else {
- ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE),
- mTftpHiiHandle, LocalFilePath, Status
- );
- }
- ShellCloseFile (&FileHandle);
-
NextHandle:
- if (Data != NULL) {
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (DataSize));
- }
-
CloseProtocolAndDestroyServiceChild (
ControllerHandle,
&gEfiMtftp4ServiceBindingProtocolGuid,
@@ -912,9 +873,6 @@ Error :
@param[in] FileSize Size of the file in number of bytes
@param[in] BlockSize Value of the TFTP blksize option
@param[in] WindowSize Value of the TFTP window size option
- @param[out] Data Address where to store the address of the buffer
- where the data of the file were downloaded in
- case of success.
@retval EFI_SUCCESS The file was downloaded.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
@@ -930,13 +888,10 @@ DownloadFile (
IN CONST CHAR8 *AsciiFilePath,
IN UINTN FileSize,
IN UINT16 BlockSize,
- IN UINT16 WindowSize,
- OUT VOID **Data
+ IN UINT16 WindowSize
)
{
EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS PagesAddress;
- VOID *Buffer;
DOWNLOAD_CONTEXT *TftpContext;
EFI_MTFTP4_TOKEN Mtftp4Token;
UINT8 BlksizeBuf[10];
@@ -944,22 +899,6 @@ DownloadFile (
ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));
- // Downloaded file can be large. BS.AllocatePages() is more faster
- // than AllocatePool() and avoid fragmentation.
- // The downloaded file could be an EFI application. Marking the
- // allocated page as EfiBootServicesCode would allow to execute a
- // potential downloaded EFI application.
- Status = gBS->AllocatePages (
- AllocateAnyPages,
- EfiBootServicesCode,
- EFI_SIZE_TO_PAGES (FileSize),
- &PagesAddress
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Buffer = (VOID*)(UINTN)PagesAddress;
TftpContext = AllocatePool (sizeof (DOWNLOAD_CONTEXT));
if (TftpContext == NULL) {
Status = EFI_OUT_OF_RESOURCES;
@@ -970,8 +909,6 @@ DownloadFile (
TftpContext->LastReportedNbOfBytes = 0;
Mtftp4Token.Filename = (UINT8*)AsciiFilePath;
- Mtftp4Token.BufferSize = FileSize;
- Mtftp4Token.Buffer = Buffer;
Mtftp4Token.CheckPacket = CheckPacket;
Mtftp4Token.Context = (VOID*)TftpContext;
Mtftp4Token.OptionCount = 0;
@@ -1000,14 +937,41 @@ DownloadFile (
mTftpHiiHandle, FilePath
);
+ //
+ // OPEN FILE
+ //
+ if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {
+ ShellDeleteFileByName (mLocalFilePath);
+ }
+
+ Status = ShellOpenFileByName (
+ mLocalFilePath,
+ &mFileHandle,
+ EFI_FILE_MODE_CREATE |
+ EFI_FILE_MODE_WRITE |
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
+ mTftpHiiHandle, L"tftp", mLocalFilePath
+ );
+ goto Error;
+ }
+
Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);
ShellPrintHiiEx (
-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF),
mTftpHiiHandle
);
-Error :
+ //
+ // CLOSE FILE
+ //
+ ShellCloseFile (&mFileHandle);
+Error :
if (TftpContext != NULL) {
FreePool (TftpContext);
}
@@ -1016,14 +980,7 @@ Error :
FreePool (Mtftp4Token.OptionList);
}
- if (EFI_ERROR (Status)) {
- gBS->FreePages (PagesAddress, EFI_SIZE_TO_PAGES (FileSize));
- return Status;
- }
-
- *Data = Buffer;
-
- return EFI_SUCCESS;
+ return Status;
}
/**
@@ -1054,6 +1011,7 @@ CheckPacket (
UINTN Index;
UINTN LastStep;
UINTN Step;
+ UINTN DownloadLen;
EFI_STATUS Status;
if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) {
@@ -1061,17 +1019,35 @@ CheckPacket (
}
Context = (DOWNLOAD_CONTEXT*)Token->Context;
- if (Context->DownloadedNbOfBytes == 0) {
- ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);
- }
//
// The data in the packet are prepended with two UINT16 :
// . OpCode = EFI_MTFTP4_OPCODE_DATA
// . Block = the number of this block of data
//
- Context->DownloadedNbOfBytes += PacketLen - sizeof (Packet->OpCode)
- - sizeof (Packet->Data.Block);
+ DownloadLen = (UINTN)PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block);
+
+ ShellSetFilePosition(mFileHandle, Context->DownloadedNbOfBytes);
+ Status = ShellWriteFile (mFileHandle, &DownloadLen, Packet->Data.Data);
+ if (EFI_ERROR (Status)) {
+ if (Context->DownloadedNbOfBytes > 0) {
+ ShellPrintHiiEx (
+ -1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF),
+ mTftpHiiHandle
+ );
+ }
+ ShellPrintHiiEx (
+ -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE),
+ mTftpHiiHandle, mLocalFilePath, Status
+ );
+ return Status;
+ }
+
+ if (Context->DownloadedNbOfBytes == 0) {
+ ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);
+ }
+
+ Context->DownloadedNbOfBytes += DownloadLen;
NbOfKb = Context->DownloadedNbOfBytes / 1024;
Progress[0] = L'\0';
--
2.18.0.windows.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v1] ShellPkg/TftpDynamicCommand: Change file writing method in tftp
2019-01-09 8:42 [PATCH v1] ShellPkg/TftpDynamicCommand: Change file writing method in tftp Songpeng Li
@ 2019-01-10 1:27 ` Wu, Jiaxin
0 siblings, 0 replies; 2+ messages in thread
From: Wu, Jiaxin @ 2019-01-10 1:27 UTC (permalink / raw)
To: Li, Songpeng, edk2-devel@lists.01.org; +Cc: Carsey, Jaben, Ni, Ray
Reviewed-by: Wu Jiaxin <jiaxin.wu@intel.com>
Thanks,
Jiaxin
> -----Original Message-----
> From: Li, Songpeng
> Sent: Wednesday, January 9, 2019 4:42 PM
> To: edk2-devel@lists.01.org
> Cc: Carsey, Jaben <jaben.carsey@intel.com>; Ni, Ray <ray.ni@intel.com>;
> Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [PATCH v1] ShellPkg/TftpDynamicCommand: Change file writing
> method in tftp
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1433
>
> Current logic of shell tftp download was writing file after tftp
> download finished, when the file is large, it looks like the shell
> tftp command hanged after download was finished. To improve
> end-user experience, the solution is using split file writing
> instead.
>
> This patch update the code to open and close file inside
> DownloadFile(), and save each packet to file within callback
> function CheckPacket().
>
> Since AllocatePage() is no-longer needed, This patch can also
> remove the memory limitation. The download file can be larger
> than system free memory now.
>
> Cc: Jaben Carsey <jaben.carsey@intel.com>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Wu Jiaxin <jiaxin.wu@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Songpeng Li <songpeng.li@intel.com>
> ---
> ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c | 152
> +++++++++-----------
> 1 file changed, 64 insertions(+), 88 deletions(-)
>
> diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
> b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
> index ed081b5bad7c..a53fe16f0683 100644
> --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
> +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
> @@ -41,6 +41,12 @@ STATIC CONST CHAR16 mTftpProgressFrame[] = L"[
> // (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'
> STATIC CONST CHAR16 mTftpProgressDelete[] =
> L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\
> b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
>
> +// Local File Handle
> +SHELL_FILE_HANDLE mFileHandle;
> +
> +// Path of the local file, Unicode encoded
> +CONST CHAR16 *mLocalFilePath;
> +
> /**
> Check and convert the UINT16 option values of the 'tftp' command
>
> @@ -166,9 +172,6 @@ GetFileSize (
> @param[in] FileSize Size of the file in number of bytes
> @param[in] BlockSize Value of the TFTP blksize option
> @param[in] WindowSize Value of the TFTP window size option
> - @param[out] Data Address where to store the address of the buffer
> - where the data of the file were downloaded in
> - case of success.
>
> @retval EFI_SUCCESS The file was downloaded.
> @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
> @@ -184,8 +187,7 @@ DownloadFile (
> IN CONST CHAR8 *AsciiFilePath,
> IN UINTN FileSize,
> IN UINT16 BlockSize,
> - IN UINT16 WindowSize,
> - OUT VOID **Data
> + IN UINT16 WindowSize
> );
>
> /**
> @@ -287,7 +289,6 @@ RunTftp (
> CHAR8 *AsciiRemoteFilePath;
> UINTN FilePathSize;
> CONST CHAR16 *Walker;
> - CONST CHAR16 *LocalFilePath;
> EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData;
> EFI_HANDLE *Handles;
> UINTN HandleCount;
> @@ -297,9 +298,7 @@ RunTftp (
> EFI_HANDLE Mtftp4ChildHandle;
> EFI_MTFTP4_PROTOCOL *Mtftp4;
> UINTN FileSize;
> - UINTN DataSize;
> VOID *Data;
> - SHELL_FILE_HANDLE FileHandle;
> UINT16 BlockSize;
> UINT16 WindowSize;
>
> @@ -309,7 +308,6 @@ RunTftp (
> AsciiRemoteFilePath = NULL;
> Handles = NULL;
> FileSize = 0;
> - DataSize = 0;
> BlockSize = MTFTP_DEFAULT_BLKSIZE;
> WindowSize = MTFTP_DEFAULT_WINDOWSIZE;
>
> @@ -385,7 +383,7 @@ RunTftp (
> UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);
>
> if (ParamCount == 4) {
> - LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
> + mLocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
> } else {
> Walker = RemoteFilePath + StrLen (RemoteFilePath);
> while ((--Walker) >= RemoteFilePath) {
> @@ -394,7 +392,7 @@ RunTftp (
> break;
> }
> }
> - LocalFilePath = Walker + 1;
> + mLocalFilePath = Walker + 1;
> }
>
> //
> @@ -543,7 +541,7 @@ RunTftp (
> goto NextHandle;
> }
>
> - Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath,
> FileSize, BlockSize, WindowSize, &Data);
> + Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath,
> FileSize, BlockSize, WindowSize);
> if (EFI_ERROR (Status)) {
> ShellPrintHiiEx (
> -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),
> @@ -552,45 +550,8 @@ RunTftp (
> goto NextHandle;
> }
>
> - DataSize = FileSize;
> -
> - if (!EFI_ERROR (ShellFileExists (LocalFilePath))) {
> - ShellDeleteFileByName (LocalFilePath);
> - }
> -
> - Status = ShellOpenFileByName (
> - LocalFilePath,
> - &FileHandle,
> - EFI_FILE_MODE_CREATE |
> - EFI_FILE_MODE_WRITE |
> - EFI_FILE_MODE_READ,
> - 0
> - );
> - if (EFI_ERROR (Status)) {
> - ShellPrintHiiEx (
> - -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
> - mTftpHiiHandle, L"tftp", LocalFilePath
> - );
> - goto NextHandle;
> - }
> -
> - Status = ShellWriteFile (FileHandle, &FileSize, Data);
> - if (!EFI_ERROR (Status)) {
> - ShellStatus = SHELL_SUCCESS;
> - } else {
> - ShellPrintHiiEx (
> - -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE),
> - mTftpHiiHandle, LocalFilePath, Status
> - );
> - }
> - ShellCloseFile (&FileHandle);
> -
> NextHandle:
>
> - if (Data != NULL) {
> - gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data,
> EFI_SIZE_TO_PAGES (DataSize));
> - }
> -
> CloseProtocolAndDestroyServiceChild (
> ControllerHandle,
> &gEfiMtftp4ServiceBindingProtocolGuid,
> @@ -912,9 +873,6 @@ Error :
> @param[in] FileSize Size of the file in number of bytes
> @param[in] BlockSize Value of the TFTP blksize option
> @param[in] WindowSize Value of the TFTP window size option
> - @param[out] Data Address where to store the address of the buffer
> - where the data of the file were downloaded in
> - case of success.
>
> @retval EFI_SUCCESS The file was downloaded.
> @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
> @@ -930,13 +888,10 @@ DownloadFile (
> IN CONST CHAR8 *AsciiFilePath,
> IN UINTN FileSize,
> IN UINT16 BlockSize,
> - IN UINT16 WindowSize,
> - OUT VOID **Data
> + IN UINT16 WindowSize
> )
> {
> EFI_STATUS Status;
> - EFI_PHYSICAL_ADDRESS PagesAddress;
> - VOID *Buffer;
> DOWNLOAD_CONTEXT *TftpContext;
> EFI_MTFTP4_TOKEN Mtftp4Token;
> UINT8 BlksizeBuf[10];
> @@ -944,22 +899,6 @@ DownloadFile (
>
> ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));
>
> - // Downloaded file can be large. BS.AllocatePages() is more faster
> - // than AllocatePool() and avoid fragmentation.
> - // The downloaded file could be an EFI application. Marking the
> - // allocated page as EfiBootServicesCode would allow to execute a
> - // potential downloaded EFI application.
> - Status = gBS->AllocatePages (
> - AllocateAnyPages,
> - EfiBootServicesCode,
> - EFI_SIZE_TO_PAGES (FileSize),
> - &PagesAddress
> - );
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> -
> - Buffer = (VOID*)(UINTN)PagesAddress;
> TftpContext = AllocatePool (sizeof (DOWNLOAD_CONTEXT));
> if (TftpContext == NULL) {
> Status = EFI_OUT_OF_RESOURCES;
> @@ -970,8 +909,6 @@ DownloadFile (
> TftpContext->LastReportedNbOfBytes = 0;
>
> Mtftp4Token.Filename = (UINT8*)AsciiFilePath;
> - Mtftp4Token.BufferSize = FileSize;
> - Mtftp4Token.Buffer = Buffer;
> Mtftp4Token.CheckPacket = CheckPacket;
> Mtftp4Token.Context = (VOID*)TftpContext;
> Mtftp4Token.OptionCount = 0;
> @@ -1000,14 +937,41 @@ DownloadFile (
> mTftpHiiHandle, FilePath
> );
>
> + //
> + // OPEN FILE
> + //
> + if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {
> + ShellDeleteFileByName (mLocalFilePath);
> + }
> +
> + Status = ShellOpenFileByName (
> + mLocalFilePath,
> + &mFileHandle,
> + EFI_FILE_MODE_CREATE |
> + EFI_FILE_MODE_WRITE |
> + EFI_FILE_MODE_READ,
> + 0
> + );
> + if (EFI_ERROR (Status)) {
> + ShellPrintHiiEx (
> + -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
> + mTftpHiiHandle, L"tftp", mLocalFilePath
> + );
> + goto Error;
> + }
> +
> Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);
> ShellPrintHiiEx (
> -1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF),
> mTftpHiiHandle
> );
>
> -Error :
> + //
> + // CLOSE FILE
> + //
> + ShellCloseFile (&mFileHandle);
>
> +Error :
> if (TftpContext != NULL) {
> FreePool (TftpContext);
> }
> @@ -1016,14 +980,7 @@ Error :
> FreePool (Mtftp4Token.OptionList);
> }
>
> - if (EFI_ERROR (Status)) {
> - gBS->FreePages (PagesAddress, EFI_SIZE_TO_PAGES (FileSize));
> - return Status;
> - }
> -
> - *Data = Buffer;
> -
> - return EFI_SUCCESS;
> + return Status;
> }
>
> /**
> @@ -1054,6 +1011,7 @@ CheckPacket (
> UINTN Index;
> UINTN LastStep;
> UINTN Step;
> + UINTN DownloadLen;
> EFI_STATUS Status;
>
> if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) {
> @@ -1061,17 +1019,35 @@ CheckPacket (
> }
>
> Context = (DOWNLOAD_CONTEXT*)Token->Context;
> - if (Context->DownloadedNbOfBytes == 0) {
> - ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);
> - }
>
> //
> // The data in the packet are prepended with two UINT16 :
> // . OpCode = EFI_MTFTP4_OPCODE_DATA
> // . Block = the number of this block of data
> //
> - Context->DownloadedNbOfBytes += PacketLen - sizeof (Packet->OpCode)
> - - sizeof (Packet->Data.Block);
> + DownloadLen = (UINTN)PacketLen - sizeof (Packet->OpCode) - sizeof
> (Packet->Data.Block);
> +
> + ShellSetFilePosition(mFileHandle, Context->DownloadedNbOfBytes);
> + Status = ShellWriteFile (mFileHandle, &DownloadLen, Packet->Data.Data);
> + if (EFI_ERROR (Status)) {
> + if (Context->DownloadedNbOfBytes > 0) {
> + ShellPrintHiiEx (
> + -1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF),
> + mTftpHiiHandle
> + );
> + }
> + ShellPrintHiiEx (
> + -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE),
> + mTftpHiiHandle, mLocalFilePath, Status
> + );
> + return Status;
> + }
> +
> + if (Context->DownloadedNbOfBytes == 0) {
> + ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);
> + }
> +
> + Context->DownloadedNbOfBytes += DownloadLen;
> NbOfKb = Context->DownloadedNbOfBytes / 1024;
>
> Progress[0] = L'\0';
> --
> 2.18.0.windows.1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-01-10 1:27 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-09 8:42 [PATCH v1] ShellPkg/TftpDynamicCommand: Change file writing method in tftp Songpeng Li
2019-01-10 1:27 ` Wu, Jiaxin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox