X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ShellPkg%2FDynamicCommand%2FTftpDynamicCommand%2FTftp.c;h=7e5c73b3daaa82b11a2e1904f841f5a85f58b32e;hb=HEAD;hp=44be6d4e76f4bd754b007ba00d024797664a684f;hpb=280f49b81170aee9176a47085b168ff3bc9fd3e7;p=mirror_edk2.git
diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
index 44be6d4e76..7e5c73b3da 100644
--- a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
+++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
@@ -5,27 +5,21 @@
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett Packard Enterprise Development LP
- 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
- http://opensource.org/licenses/bsd-license.php.
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Tftp.h"
-#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32
-EFI_HANDLE mTftpHiiHandle;
+#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32
+EFI_HII_HANDLE mTftpHiiHandle;
/*
Constant strings and definitions related to the message indicating the amount of
- progress in the dowloading of a TFTP file.
+ progress in the downloading of a TFTP file.
*/
// Frame for the progression slider
-STATIC CONST CHAR16 mTftpProgressFrame[] = L"[ ]";
+STATIC CONST CHAR16 mTftpProgressFrame[] = L"[ ]";
// Number of steps in the progression slider
#define TFTP_PROGRESS_SLIDER_STEPS ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3)
@@ -39,7 +33,13 @@ STATIC CONST CHAR16 mTftpProgressFrame[] = L"[
// String to delete the TFTP progress message to be able to update it :
// (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";
+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
@@ -48,7 +48,7 @@ STATIC CONST CHAR16 mTftpProgressDelete[] = L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b
@param[out] Value UINT16 value
@return TRUE The value was returned.
- @return FALSE A parsing error occured.
+ @return FALSE A parsing error occurred.
**/
STATIC
BOOLEAN
@@ -165,9 +165,7 @@ GetFileSize (
@param[in] AsciiFilePath Path of the file, ASCII encoded
@param[in] FileSize Size of the file in number of bytes
@param[in] BlockSize Value of the TFTP blksize 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.
+ @param[in] WindowSize Value of the TFTP window size option
@retval EFI_SUCCESS The file was downloaded.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
@@ -183,7 +181,7 @@ DownloadFile (
IN CONST CHAR8 *AsciiFilePath,
IN UINTN FileSize,
IN UINT16 BlockSize,
- OUT VOID **Data
+ IN UINT16 WindowSize
);
/**
@@ -208,38 +206,57 @@ CheckPacket (
IN EFI_MTFTP4_PACKET *Packet
);
-EFI_MTFTP4_CONFIG_DATA DefaultMtftp4ConfigData = {
+EFI_MTFTP4_CONFIG_DATA DefaultMtftp4ConfigData = {
TRUE, // Use default setting
- { { 0, 0, 0, 0 } }, // StationIp - Not relevant as UseDefaultSetting=TRUE
- { { 0, 0, 0, 0 } }, // SubnetMask - Not relevant as UseDefaultSetting=TRUE
+ {
+ { 0, 0, 0, 0 }
+ }, // StationIp - Not relevant as UseDefaultSetting=TRUE
+ {
+ { 0, 0, 0, 0 }
+ }, // SubnetMask - Not relevant as UseDefaultSetting=TRUE
0, // LocalPort - Automatically assigned port number.
- { { 0, 0, 0, 0 } }, // GatewayIp - Not relevant as UseDefaultSetting=TRUE
- { { 0, 0, 0, 0 } }, // ServerIp - Not known yet
+ {
+ { 0, 0, 0, 0 }
+ }, // GatewayIp - Not relevant as UseDefaultSetting=TRUE
+ {
+ { 0, 0, 0, 0 }
+ }, // ServerIp - Not known yet
69, // InitialServerPort - Standard TFTP server port
- 6, // TryCount - Max number of retransmissions.
+ 6, // TryCount - The number of times to transmit request packets and wait for a response.
4 // TimeoutValue - Retransmission timeout in seconds.
};
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- {L"-i", TypeValue},
- {L"-l", TypeValue},
- {L"-r", TypeValue},
- {L"-c", TypeValue},
- {L"-t", TypeValue},
- {L"-s", TypeValue},
- {NULL , TypeMax}
- };
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ { L"-i", TypeValue },
+ { L"-l", TypeValue },
+ { L"-r", TypeValue },
+ { L"-c", TypeValue },
+ { L"-t", TypeValue },
+ { L"-s", TypeValue },
+ { L"-w", TypeValue },
+ { NULL, TypeMax }
+};
///
/// The default block size (512) of tftp is defined in the RFC1350.
///
-#define MTFTP_DEFAULT_BLKSIZE 512
+#define MTFTP_DEFAULT_BLKSIZE 512
///
/// The valid range of block size option is defined in the RFC2348.
///
-#define MTFTP_MIN_BLKSIZE 8
-#define MTFTP_MAX_BLKSIZE 65464
-
+#define MTFTP_MIN_BLKSIZE 8
+#define MTFTP_MAX_BLKSIZE 65464
+///
+/// The default windowsize (1) of tftp.
+///
+#define MTFTP_DEFAULT_WINDOWSIZE 1
+///
+/// The valid range of window size option.
+/// Note that: RFC 7440 does not mention max window size value, but for the
+/// stability reason, the value is limited to 64.
+///
+#define MTFTP_MIN_WINDOWSIZE 1
+#define MTFTP_MAX_WINDOWSIZE 64
/**
Function for 'tftp' command.
@@ -274,7 +291,6 @@ RunTftp (
CHAR8 *AsciiRemoteFilePath;
UINTN FilePathSize;
CONST CHAR16 *Walker;
- CONST CHAR16 *LocalFilePath;
EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData;
EFI_HANDLE *Handles;
UINTN HandleCount;
@@ -284,10 +300,8 @@ RunTftp (
EFI_HANDLE Mtftp4ChildHandle;
EFI_MTFTP4_PROTOCOL *Mtftp4;
UINTN FileSize;
- UINTN DataSize;
- VOID *Data;
- SHELL_FILE_HANDLE FileHandle;
UINT16 BlockSize;
+ UINT16 WindowSize;
ShellStatus = SHELL_INVALID_PARAMETER;
ProblemParam = NULL;
@@ -295,8 +309,8 @@ RunTftp (
AsciiRemoteFilePath = NULL;
Handles = NULL;
FileSize = 0;
- DataSize = 0;
BlockSize = MTFTP_DEFAULT_BLKSIZE;
+ WindowSize = MTFTP_DEFAULT_WINDOWSIZE;
//
// Initialize the Shell library (we must be in non-auto-init...)
@@ -313,15 +327,22 @@ RunTftp (
Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);
if (EFI_ERROR (Status)) {
if ((Status == EFI_VOLUME_CORRUPTED) &&
- (ProblemParam != NULL) ) {
+ (ProblemParam != NULL))
+ {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), mTftpHiiHandle,
- L"tftp", ProblemParam
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PROBLEM),
+ mTftpHiiHandle,
+ L"tftp",
+ ProblemParam
);
FreePool (ProblemParam);
} else {
ASSERT (FALSE);
}
+
goto Error;
}
@@ -331,15 +352,24 @@ RunTftp (
ParamCount = ShellCommandLineGetCount (CheckPackage);
if (ParamCount > 4) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY),
- mTftpHiiHandle, L"tftp"
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_TOO_MANY),
+ mTftpHiiHandle,
+ L"tftp"
);
goto Error;
}
+
if (ParamCount < 3) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW),
- mTftpHiiHandle, L"tftp"
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_TOO_FEW),
+ mTftpHiiHandle,
+ L"tftp"
);
goto Error;
}
@@ -350,36 +380,44 @@ RunTftp (
// Check the host IPv4 address
//
ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);
- Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);
+ Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle, L"tftp", ValueStr
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PARAM_INV),
+ mTftpHiiHandle,
+ L"tftp",
+ ValueStr
+ );
goto Error;
}
RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
- ASSERT(RemoteFilePath != NULL);
- FilePathSize = StrLen (RemoteFilePath) + 1;
+ ASSERT (RemoteFilePath != NULL);
+ FilePathSize = StrLen (RemoteFilePath) + 1;
AsciiRemoteFilePath = AllocatePool (FilePathSize);
if (AsciiRemoteFilePath == NULL) {
ShellStatus = SHELL_OUT_OF_RESOURCES;
goto Error;
}
+
UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);
if (ParamCount == 4) {
- LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
+ mLocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
} else {
Walker = RemoteFilePath + StrLen (RemoteFilePath);
while ((--Walker) >= RemoteFilePath) {
if ((*Walker == L'\\') ||
- (*Walker == L'/' ) ) {
+ (*Walker == L'/'))
+ {
break;
}
}
- LocalFilePath = Walker + 1;
+
+ mLocalFilePath = Walker + 1;
}
//
@@ -406,6 +444,10 @@ RunTftp (
if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) {
goto Error;
}
+
+ if (Mtftp4ConfigData.TryCount == 0) {
+ Mtftp4ConfigData.TryCount = 6;
+ }
}
ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");
@@ -413,11 +455,17 @@ RunTftp (
if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) {
goto Error;
}
+
if (Mtftp4ConfigData.TimeoutValue == 0) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle, L"tftp", ValueStr
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PARAM_INV),
+ mTftpHiiHandle,
+ L"tftp",
+ ValueStr
+ );
goto Error;
}
}
@@ -427,11 +475,37 @@ RunTftp (
if (!StringToUint16 (ValueStr, &BlockSize)) {
goto Error;
}
- if (BlockSize < MTFTP_MIN_BLKSIZE || BlockSize > MTFTP_MAX_BLKSIZE) {
+
+ if ((BlockSize < MTFTP_MIN_BLKSIZE) || (BlockSize > MTFTP_MAX_BLKSIZE)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle, L"tftp", ValueStr
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PARAM_INV),
+ mTftpHiiHandle,
+ L"tftp",
+ ValueStr
+ );
+ goto Error;
+ }
+ }
+
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-w");
+ if (ValueStr != NULL) {
+ if (!StringToUint16 (ValueStr, &WindowSize)) {
+ goto Error;
+ }
+
+ if ((WindowSize < MTFTP_MIN_WINDOWSIZE) || (WindowSize > MTFTP_MAX_WINDOWSIZE)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PARAM_INV),
+ mTftpHiiHandle,
+ L"tftp",
+ ValueStr
+ );
goto Error;
}
}
@@ -440,33 +514,41 @@ RunTftp (
// Locate all MTFTP4 Service Binding protocols
//
ShellStatus = SHELL_NOT_FOUND;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiManagedNetworkServiceBindingProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiManagedNetworkServiceBindingProtocolGuid,
+ NULL,
+ &HandleCount,
+ &Handles
+ );
if (EFI_ERROR (Status) || (HandleCount == 0)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NO_NIC),
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_ERR_NO_NIC),
mTftpHiiHandle
- );
+ );
goto Error;
}
for (NicNumber = 0;
(NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS);
- NicNumber++) {
+ NicNumber++)
+ {
ControllerHandle = Handles[NicNumber];
- Data = NULL;
Status = GetNicName (ControllerHandle, NicNumber, NicName);
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NAME),
- mTftpHiiHandle, NicNumber, Status
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_ERR_NIC_NAME),
+ mTftpHiiHandle,
+ NicNumber,
+ Status
+ );
continue;
}
@@ -474,6 +556,7 @@ RunTftp (
if (StrCmp (NicName, UserNicName) != 0) {
continue;
}
+
NicFound = TRUE;
}
@@ -482,81 +565,68 @@ RunTftp (
&gEfiMtftp4ServiceBindingProtocolGuid,
&gEfiMtftp4ProtocolGuid,
&Mtftp4ChildHandle,
- (VOID**)&Mtftp4
+ (VOID **)&Mtftp4
);
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),
- mTftpHiiHandle, NicName, Status
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),
+ mTftpHiiHandle,
+ NicName,
+ Status
+ );
continue;
}
Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData);
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_CONFIGURE),
- mTftpHiiHandle, NicName, Status
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_ERR_CONFIGURE),
+ mTftpHiiHandle,
+ NicName,
+ Status
+ );
goto NextHandle;
}
Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize);
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE),
- mTftpHiiHandle, RemoteFilePath, NicName, Status
- );
- goto NextHandle;
- }
-
- Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, &Data);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),
- mTftpHiiHandle, RemoteFilePath, NicName, Status
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE),
+ mTftpHiiHandle,
+ RemoteFilePath,
+ NicName,
+ Status
+ );
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
- );
+ Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize);
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
- mTftpHiiHandle, L"tftp", LocalFilePath
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),
+ mTftpHiiHandle,
+ RemoteFilePath,
+ NicName,
+ Status
+ );
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);
+ ShellStatus = SHELL_SUCCESS;
- NextHandle:
-
- if (Data != NULL) {
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (DataSize));
- }
+NextHandle:
CloseProtocolAndDestroyServiceChild (
ControllerHandle,
@@ -568,21 +638,30 @@ RunTftp (
if ((UserNicName != NULL) && (!NicFound)) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),
- mTftpHiiHandle, UserNicName
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),
+ mTftpHiiHandle,
+ UserNicName
+ );
}
- Error:
+Error:
ShellCommandLineFreeVarList (CheckPackage);
if (AsciiRemoteFilePath != NULL) {
FreePool (AsciiRemoteFilePath);
}
+
if (Handles != NULL) {
FreePool (Handles);
}
+ if ((ShellStatus != SHELL_SUCCESS) && (EFI_ERROR (Status))) {
+ ShellStatus = Status & ~MAX_BIT;
+ }
+
return ShellStatus;
}
@@ -593,7 +672,7 @@ RunTftp (
@param[out] Value UINT16 value
@return TRUE The value was returned.
- @return FALSE A parsing error occured.
+ @return FALSE A parsing error occurred.
**/
STATIC
BOOLEAN
@@ -607,9 +686,14 @@ StringToUint16 (
Val = ShellStrToUintn (ValueStr);
if (Val > MAX_UINT16) {
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),
- mTftpHiiHandle, L"tftp", ValueStr
- );
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PARAM_INV),
+ mTftpHiiHandle,
+ L"tftp",
+ ValueStr
+ );
return FALSE;
}
@@ -653,7 +737,7 @@ GetNicName (
&gEfiManagedNetworkServiceBindingProtocolGuid,
&gEfiManagedNetworkProtocolGuid,
&MnpHandle,
- (VOID**)&Mnp
+ (VOID **)&Mnp
);
if (EFI_ERROR (Status)) {
goto Error;
@@ -669,7 +753,7 @@ GetNicName (
IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,
SnpMode.IfType == NET_IFTYPE_ETHERNET ?
L"eth%d" :
- L"unk%d" ,
+ L"unk%d",
NicNumber
);
@@ -721,12 +805,12 @@ CreateServiceChildAndOpenProtocol (
EFI_STATUS Status;
*ChildHandle = NULL;
- Status = NetLibCreateServiceChild (
- ControllerHandle,
- gImageHandle,
- ServiceBindingProtocolGuid,
- ChildHandle
- );
+ Status = NetLibCreateServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ ServiceBindingProtocolGuid,
+ ChildHandle
+ );
if (!EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
*ChildHandle,
@@ -818,21 +902,21 @@ GetFileSize (
UINT32 OptCnt;
UINT8 OptBuf[128];
- ReqOpt[0].OptionStr = (UINT8*)"tsize";
- OptBuf[0] = '0';
- OptBuf[1] = 0;
- ReqOpt[0].ValueStr = OptBuf;
+ ReqOpt[0].OptionStr = (UINT8 *)"tsize";
+ OptBuf[0] = '0';
+ OptBuf[1] = 0;
+ ReqOpt[0].ValueStr = OptBuf;
Status = Mtftp4->GetInfo (
- Mtftp4,
- NULL,
- (UINT8*)FilePath,
- NULL,
- 1,
- ReqOpt,
- &PktLen,
- &Packet
- );
+ Mtftp4,
+ NULL,
+ (UINT8 *)FilePath,
+ NULL,
+ 1,
+ ReqOpt,
+ &PktLen,
+ &Packet
+ );
if (EFI_ERROR (Status)) {
goto Error;
@@ -842,7 +926,7 @@ GetFileSize (
Mtftp4,
PktLen,
Packet,
- (UINT32 *) &OptCnt,
+ (UINT32 *)&OptCnt,
&TableOfOptions
);
if (EFI_ERROR (Status)) {
@@ -855,16 +939,18 @@ GetFileSize (
*FileSize = AsciiStrDecimalToUintn ((CHAR8 *)Option->ValueStr);
break;
}
+
OptCnt--;
Option++;
}
+
FreePool (TableOfOptions);
if (OptCnt == 0) {
Status = EFI_UNSUPPORTED;
}
-Error :
+Error:
return Status;
}
@@ -878,9 +964,7 @@ Error :
@param[in] AsciiFilePath Path of the file, ASCII encoded
@param[in] FileSize Size of the file in number of bytes
@param[in] BlockSize Value of the TFTP blksize 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.
+ @param[in] WindowSize Value of the TFTP window size option
@retval EFI_SUCCESS The file was downloaded.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
@@ -896,82 +980,112 @@ DownloadFile (
IN CONST CHAR8 *AsciiFilePath,
IN UINTN FileSize,
IN UINT16 BlockSize,
- OUT VOID **Data
+ IN UINT16 WindowSize
)
{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS PagesAddress;
- VOID *Buffer;
- DOWNLOAD_CONTEXT *TftpContext;
- EFI_MTFTP4_TOKEN Mtftp4Token;
- EFI_MTFTP4_OPTION ReqOpt;
- UINT8 OptBuf[10];
-
- // 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;
- }
+ EFI_STATUS Status;
+ DOWNLOAD_CONTEXT *TftpContext;
+ EFI_MTFTP4_TOKEN Mtftp4Token;
+ UINT8 BlksizeBuf[10];
+ UINT8 WindowsizeBuf[10];
+
+ ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));
- Buffer = (VOID*)(UINTN)PagesAddress;
TftpContext = AllocatePool (sizeof (DOWNLOAD_CONTEXT));
if (TftpContext == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Error;
}
- TftpContext->FileSize = FileSize;
+
+ TftpContext->FileSize = FileSize;
TftpContext->DownloadedNbOfBytes = 0;
TftpContext->LastReportedNbOfBytes = 0;
- ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));
- Mtftp4Token.Filename = (UINT8*)AsciiFilePath;
- Mtftp4Token.BufferSize = FileSize;
- Mtftp4Token.Buffer = Buffer;
+ Mtftp4Token.Filename = (UINT8 *)AsciiFilePath;
Mtftp4Token.CheckPacket = CheckPacket;
- Mtftp4Token.Context = (VOID*)TftpContext;
+ Mtftp4Token.Context = (VOID *)TftpContext;
+ Mtftp4Token.OptionCount = 0;
+ Mtftp4Token.OptionList = AllocatePool (sizeof (EFI_MTFTP4_OPTION) * 2);
+ if (Mtftp4Token.OptionList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
if (BlockSize != MTFTP_DEFAULT_BLKSIZE) {
- ReqOpt.OptionStr = (UINT8 *) "blksize";
- AsciiSPrint ((CHAR8 *)OptBuf, sizeof (OptBuf), "%d", BlockSize);
- ReqOpt.ValueStr = OptBuf;
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"blksize";
+ AsciiSPrint ((CHAR8 *)BlksizeBuf, sizeof (BlksizeBuf), "%d", BlockSize);
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = BlksizeBuf;
+ Mtftp4Token.OptionCount++;
+ }
- Mtftp4Token.OptionCount = 1;
- Mtftp4Token.OptionList = &ReqOpt;
+ if (WindowSize != MTFTP_DEFAULT_WINDOWSIZE) {
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"windowsize";
+ AsciiSPrint ((CHAR8 *)WindowsizeBuf, sizeof (WindowsizeBuf), "%d", WindowSize);
+ Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = WindowsizeBuf;
+ Mtftp4Token.OptionCount++;
}
ShellPrintHiiEx (
- -1, -1, NULL, STRING_TOKEN (STR_TFTP_DOWNLOADING),
- mTftpHiiHandle, FilePath
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_TFTP_DOWNLOADING),
+ 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),
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_CRLF),
mTftpHiiHandle
);
-Error :
+ //
+ // CLOSE FILE
+ //
+ ShellCloseFile (&mFileHandle);
- if (TftpContext == NULL) {
+Error:
+ if (TftpContext != NULL) {
FreePool (TftpContext);
}
- if (EFI_ERROR (Status)) {
- gBS->FreePages (PagesAddress, EFI_SIZE_TO_PAGES (FileSize));
- return Status;
+ if (Mtftp4Token.OptionList != NULL) {
+ FreePool (Mtftp4Token.OptionList);
}
- *Data = Buffer;
-
- return EFI_SUCCESS;
+ return Status;
}
/**
@@ -1002,29 +1116,57 @@ CheckPacket (
UINTN Index;
UINTN LastStep;
UINTN Step;
+ UINTN DownloadLen;
EFI_STATUS Status;
if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) {
return EFI_SUCCESS;
}
- Context = (DOWNLOAD_CONTEXT*)Token->Context;
- if (Context->DownloadedNbOfBytes == 0) {
- ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);
- }
+ Context = (DOWNLOAD_CONTEXT *)Token->Context;
//
// 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);
- NbOfKb = Context->DownloadedNbOfBytes / 1024;
+ 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';
- LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
- Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
+ LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
+ Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;
if (Step <= LastStep) {
return EFI_SUCCESS;
@@ -1033,12 +1175,14 @@ CheckPacket (
ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete);
Status = StrCpyS (Progress, TFTP_PROGRESS_MESSAGE_SIZE, mTftpProgressFrame);
- if (EFI_ERROR(Status)) {
+ if (EFI_ERROR (Status)) {
return Status;
}
+
for (Index = 1; Index < Step; Index++) {
Progress[Index] = L'=';
}
+
Progress[Step] = L'>';
UnicodeSPrint (
@@ -1055,20 +1199,20 @@ CheckPacket (
}
/**
- Retrive HII package list from ImageHandle and publish to HII database.
+ Retrieve HII package list from ImageHandle and publish to HII database.
@param ImageHandle The image handle of the process.
@return HII handle.
**/
-EFI_HANDLE
+EFI_HII_HANDLE
InitializeHiiPackage (
- EFI_HANDLE ImageHandle
+ EFI_HANDLE ImageHandle
)
{
- EFI_STATUS Status;
- EFI_HII_PACKAGE_LIST_HEADER *PackageList;
- EFI_HANDLE HiiHandle;
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ EFI_HII_HANDLE HiiHandle;
//
// Retrieve HII package list from ImageHandle
@@ -1099,5 +1243,6 @@ InitializeHiiPackage (
if (EFI_ERROR (Status)) {
return NULL;
}
+
return HiiHandle;
}