// (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'\r
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";\r
\r
+// Local File Handle\r
+SHELL_FILE_HANDLE mFileHandle;\r
+\r
+// Path of the local file, Unicode encoded\r
+CONST CHAR16 *mLocalFilePath;\r
+\r
/**\r
Check and convert the UINT16 option values of the 'tftp' command\r
\r
@param[in] FileSize Size of the file in number of bytes\r
@param[in] BlockSize Value of the TFTP blksize option\r
@param[in] WindowSize Value of the TFTP window size option\r
- @param[out] Data Address where to store the address of the buffer\r
- where the data of the file were downloaded in\r
- case of success.\r
\r
@retval EFI_SUCCESS The file was downloaded.\r
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
IN CONST CHAR8 *AsciiFilePath,\r
IN UINTN FileSize,\r
IN UINT16 BlockSize,\r
- IN UINT16 WindowSize,\r
- OUT VOID **Data\r
+ IN UINT16 WindowSize\r
);\r
\r
/**\r
CHAR8 *AsciiRemoteFilePath;\r
UINTN FilePathSize;\r
CONST CHAR16 *Walker;\r
- CONST CHAR16 *LocalFilePath;\r
EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData;\r
EFI_HANDLE *Handles;\r
UINTN HandleCount;\r
EFI_HANDLE Mtftp4ChildHandle;\r
EFI_MTFTP4_PROTOCOL *Mtftp4;\r
UINTN FileSize;\r
- UINTN DataSize;\r
- VOID *Data;\r
- SHELL_FILE_HANDLE FileHandle;\r
UINT16 BlockSize;\r
UINT16 WindowSize;\r
\r
AsciiRemoteFilePath = NULL;\r
Handles = NULL;\r
FileSize = 0;\r
- DataSize = 0;\r
BlockSize = MTFTP_DEFAULT_BLKSIZE;\r
WindowSize = MTFTP_DEFAULT_WINDOWSIZE;\r
\r
UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);\r
\r
if (ParamCount == 4) {\r
- LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);\r
+ mLocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);\r
} else {\r
Walker = RemoteFilePath + StrLen (RemoteFilePath);\r
while ((--Walker) >= RemoteFilePath) {\r
break;\r
}\r
}\r
- LocalFilePath = Walker + 1;\r
+ mLocalFilePath = Walker + 1;\r
}\r
\r
//\r
(NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS);\r
NicNumber++) {\r
ControllerHandle = Handles[NicNumber];\r
- Data = NULL;\r
\r
Status = GetNicName (ControllerHandle, NicNumber, NicName);\r
if (EFI_ERROR (Status)) {\r
goto NextHandle;\r
}\r
\r
- Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize, &Data);\r
+ Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize);\r
if (EFI_ERROR (Status)) {\r
ShellPrintHiiEx (\r
-1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),\r
goto NextHandle;\r
}\r
\r
- DataSize = FileSize;\r
-\r
- if (!EFI_ERROR (ShellFileExists (LocalFilePath))) {\r
- ShellDeleteFileByName (LocalFilePath);\r
- }\r
-\r
- Status = ShellOpenFileByName (\r
- LocalFilePath,\r
- &FileHandle,\r
- EFI_FILE_MODE_CREATE |\r
- EFI_FILE_MODE_WRITE |\r
- EFI_FILE_MODE_READ,\r
- 0\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),\r
- mTftpHiiHandle, L"tftp", LocalFilePath\r
- );\r
- goto NextHandle;\r
- }\r
-\r
- Status = ShellWriteFile (FileHandle, &FileSize, Data);\r
- if (!EFI_ERROR (Status)) {\r
- ShellStatus = SHELL_SUCCESS;\r
- } else {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE),\r
- mTftpHiiHandle, LocalFilePath, Status\r
- );\r
- }\r
- ShellCloseFile (&FileHandle);\r
-\r
NextHandle:\r
\r
- if (Data != NULL) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (DataSize));\r
- }\r
-\r
CloseProtocolAndDestroyServiceChild (\r
ControllerHandle,\r
&gEfiMtftp4ServiceBindingProtocolGuid,\r
@param[in] FileSize Size of the file in number of bytes\r
@param[in] BlockSize Value of the TFTP blksize option\r
@param[in] WindowSize Value of the TFTP window size option\r
- @param[out] Data Address where to store the address of the buffer\r
- where the data of the file were downloaded in\r
- case of success.\r
\r
@retval EFI_SUCCESS The file was downloaded.\r
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
IN CONST CHAR8 *AsciiFilePath,\r
IN UINTN FileSize,\r
IN UINT16 BlockSize,\r
- IN UINT16 WindowSize,\r
- OUT VOID **Data\r
+ IN UINT16 WindowSize\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS PagesAddress;\r
- VOID *Buffer;\r
DOWNLOAD_CONTEXT *TftpContext;\r
EFI_MTFTP4_TOKEN Mtftp4Token;\r
UINT8 BlksizeBuf[10];\r
\r
ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));\r
\r
- // Downloaded file can be large. BS.AllocatePages() is more faster\r
- // than AllocatePool() and avoid fragmentation.\r
- // The downloaded file could be an EFI application. Marking the\r
- // allocated page as EfiBootServicesCode would allow to execute a\r
- // potential downloaded EFI application.\r
- Status = gBS->AllocatePages (\r
- AllocateAnyPages,\r
- EfiBootServicesCode,\r
- EFI_SIZE_TO_PAGES (FileSize),\r
- &PagesAddress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Buffer = (VOID*)(UINTN)PagesAddress;\r
TftpContext = AllocatePool (sizeof (DOWNLOAD_CONTEXT));\r
if (TftpContext == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
TftpContext->LastReportedNbOfBytes = 0;\r
\r
Mtftp4Token.Filename = (UINT8*)AsciiFilePath;\r
- Mtftp4Token.BufferSize = FileSize;\r
- Mtftp4Token.Buffer = Buffer;\r
Mtftp4Token.CheckPacket = CheckPacket;\r
Mtftp4Token.Context = (VOID*)TftpContext;\r
Mtftp4Token.OptionCount = 0;\r
mTftpHiiHandle, FilePath\r
);\r
\r
+ //\r
+ // OPEN FILE\r
+ //\r
+ if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {\r
+ ShellDeleteFileByName (mLocalFilePath);\r
+ }\r
+\r
+ Status = ShellOpenFileByName (\r
+ mLocalFilePath,\r
+ &mFileHandle,\r
+ EFI_FILE_MODE_CREATE |\r
+ EFI_FILE_MODE_WRITE |\r
+ EFI_FILE_MODE_READ,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),\r
+ mTftpHiiHandle, L"tftp", mLocalFilePath\r
+ );\r
+ goto Error;\r
+ }\r
+\r
Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);\r
ShellPrintHiiEx (\r
-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF),\r
mTftpHiiHandle\r
);\r
\r
-Error :\r
+ //\r
+ // CLOSE FILE\r
+ //\r
+ ShellCloseFile (&mFileHandle);\r
\r
+Error :\r
if (TftpContext != NULL) {\r
FreePool (TftpContext);\r
}\r
FreePool (Mtftp4Token.OptionList);\r
}\r
\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages (PagesAddress, EFI_SIZE_TO_PAGES (FileSize));\r
- return Status;\r
- }\r
-\r
- *Data = Buffer;\r
-\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r
\r
/**\r
UINTN Index;\r
UINTN LastStep;\r
UINTN Step;\r
+ UINTN DownloadLen;\r
EFI_STATUS Status;\r
\r
if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) {\r
}\r
\r
Context = (DOWNLOAD_CONTEXT*)Token->Context;\r
- if (Context->DownloadedNbOfBytes == 0) {\r
- ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);\r
- }\r
\r
//\r
// The data in the packet are prepended with two UINT16 :\r
// . OpCode = EFI_MTFTP4_OPCODE_DATA\r
// . Block = the number of this block of data\r
//\r
- Context->DownloadedNbOfBytes += PacketLen - sizeof (Packet->OpCode)\r
- - sizeof (Packet->Data.Block);\r
+ DownloadLen = (UINTN)PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block);\r
+\r
+ ShellSetFilePosition(mFileHandle, Context->DownloadedNbOfBytes);\r
+ Status = ShellWriteFile (mFileHandle, &DownloadLen, Packet->Data.Data);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Context->DownloadedNbOfBytes > 0) {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF),\r
+ mTftpHiiHandle\r
+ );\r
+ }\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE),\r
+ mTftpHiiHandle, mLocalFilePath, Status\r
+ );\r
+ return Status;\r
+ }\r
+\r
+ if (Context->DownloadedNbOfBytes == 0) {\r
+ ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);\r
+ }\r
+\r
+ Context->DownloadedNbOfBytes += DownloadLen;\r
NbOfKb = Context->DownloadedNbOfBytes / 1024;\r
\r
Progress[0] = L'\0';\r