The implementation for the 'tftp' Shell command.\r
\r
Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved. <BR>\r
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
#include "UefiShellTftpCommandLib.h"\r
\r
+#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32\r
+\r
/*\r
Constant strings and definitions related to the message indicating the amount of\r
progress in the dowloading of a TFTP file.\r
@param[in] NicNumber The network physical device number.\r
@param[out] NicName Address where to store the NIC name.\r
The memory area has to be at least\r
- IP4_NIC_NAME_LENGTH bytes wide.\r
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH \r
+ double byte wide.\r
\r
@return EFI_SUCCESS The name of the NIC was returned.\r
@return Others The creation of the child for the Managed\r
EFI_STATUS \r
GetNicName (\r
IN EFI_HANDLE ControllerHandle,\r
- IN UINTN Index,\r
+ IN UINTN NicNumber,\r
OUT CHAR16 *NicName\r
);\r
\r
@param[in] FilePath Path of the file, Unicode encoded\r
@param[in] AsciiFilePath Path of the file, ASCII encoded\r
@param[in] FileSize Size of the file in number of bytes\r
+ @param[in] BlockSize Value of the TFTP blksize 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
IN CONST CHAR16 *FilePath,\r
IN CONST CHAR8 *AsciiFilePath,\r
IN UINTN FileSize,\r
+ IN UINT16 BlockSize,\r
OUT VOID **Data\r
);\r
\r
**/\r
STATIC \r
EFI_STATUS \r
+EFIAPI\r
CheckPacket (\r
IN EFI_MTFTP4_PROTOCOL *This,\r
IN EFI_MTFTP4_TOKEN *Token,\r
{L"-r", TypeValue},\r
{L"-c", TypeValue},\r
{L"-t", TypeValue},\r
+ {L"-s", TypeValue},\r
{NULL , TypeMax}\r
};\r
\r
+///\r
+/// The default block size (512) of tftp is defined in the RFC1350.\r
+///\r
+#define MTFTP_DEFAULT_BLKSIZE 512\r
+///\r
+/// The valid range of block size option is defined in the RFC2348.\r
+///\r
+#define MTFTP_MIN_BLKSIZE 8\r
+#define MTFTP_MAX_BLKSIZE 65464\r
+\r
+\r
/**\r
Function for 'tftp' command.\r
\r
CONST CHAR16 *ValueStr;\r
CONST CHAR16 *RemoteFilePath;\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
UINTN NicNumber;\r
- CHAR16 NicName[IP4_NIC_NAME_LENGTH];\r
+ CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH];\r
EFI_HANDLE ControllerHandle;\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
\r
ShellStatus = SHELL_INVALID_PARAMETER;\r
ProblemParam = NULL;\r
NicFound = FALSE;\r
AsciiRemoteFilePath = NULL;\r
Handles = NULL;\r
+ FileSize = 0;\r
+ DataSize = 0;\r
+ BlockSize = MTFTP_DEFAULT_BLKSIZE;\r
\r
//\r
// Initialize the Shell library (we must be in non-auto-init...)\r
goto Error;\r
}\r
\r
- Mtftp4ConfigData = DefaultMtftp4ConfigData;\r
+ CopyMem (&Mtftp4ConfigData, &DefaultMtftp4ConfigData, sizeof (EFI_MTFTP4_CONFIG_DATA));\r
\r
//\r
// Check the host IPv4 address\r
}\r
\r
RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);\r
- AsciiRemoteFilePath = AllocatePool (\r
- (StrLen (RemoteFilePath) + 1) * sizeof (CHAR8)\r
- );\r
+ ASSERT(RemoteFilePath != NULL);\r
+ FilePathSize = StrLen (RemoteFilePath) + 1;\r
+ AsciiRemoteFilePath = AllocatePool (FilePathSize);\r
if (AsciiRemoteFilePath == NULL) {\r
ShellStatus = SHELL_OUT_OF_RESOURCES;\r
goto Error;\r
}\r
- UnicodeStrToAsciiStr (RemoteFilePath, AsciiRemoteFilePath);\r
+ UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);\r
\r
if (ParamCount == 4) {\r
LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);\r
}\r
}\r
\r
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s");\r
+ if (ValueStr != NULL) {\r
+ if (!StringToUint16 (ValueStr, &BlockSize)) {\r
+ goto Error;\r
+ }\r
+ if (BlockSize < MTFTP_MIN_BLKSIZE || BlockSize > MTFTP_MAX_BLKSIZE) {\r
+ ShellPrintHiiEx (\r
+ -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
+ gShellTftpHiiHandle, L"tftp", ValueStr\r
+ );\r
+ goto Error;\r
+ }\r
+ }\r
+\r
//\r
// Locate all MTFTP4 Service Binding protocols\r
//\r
goto NextHandle;\r
}\r
\r
- Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, &Data);\r
+ Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, &Data);\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
Status = ShellWriteFile (FileHandle, &FileSize, Data);\r
if (!EFI_ERROR (Status)) {\r
ShellStatus = SHELL_SUCCESS;\r
NextHandle:\r
\r
if (Data != NULL) {\r
- gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (FileSize));\r
+ gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (DataSize));\r
}\r
\r
CloseProtocolAndDestroyServiceChild (\r
);\r
}\r
\r
- if ((UserNicName != NULL) && (NicFound == FALSE)) {\r
+ if ((UserNicName != NULL) && (!NicFound)) {\r
ShellPrintHiiEx (\r
-1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),\r
gShellTftpHiiHandle, UserNicName\r
return FALSE;\r
}\r
\r
- *Value = Val;\r
+ *Value = (UINT16)Val;\r
return TRUE;\r
}\r
\r
@param[in] NicNumber The network physical device number.\r
@param[out] NicName Address where to store the NIC name.\r
The memory area has to be at least\r
- IP4_NIC_NAME_LENGTH bytes wide.\r
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH \r
+ double byte wide.\r
\r
@return EFI_SUCCESS The name of the NIC was returned.\r
@return Others The creation of the child for the Managed\r
\r
UnicodeSPrint (\r
NicName,\r
- IP4_NIC_NAME_LENGTH,\r
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,\r
SnpMode.IfType == NET_IFTYPE_ETHERNET ?\r
L"eth%d" :\r
L"unk%d" ,\r
@param[in] FilePath Path of the file, Unicode encoded\r
@param[in] AsciiFilePath Path of the file, ASCII encoded\r
@param[in] FileSize Size of the file in number of bytes\r
+ @param[in] BlockSize Value of the TFTP blksize 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
IN CONST CHAR16 *FilePath,\r
IN CONST CHAR8 *AsciiFilePath,\r
IN UINTN FileSize,\r
+ IN UINT16 BlockSize,\r
OUT VOID **Data\r
)\r
{\r
VOID *Buffer;\r
DOWNLOAD_CONTEXT *TftpContext;\r
EFI_MTFTP4_TOKEN Mtftp4Token;\r
+ EFI_MTFTP4_OPTION ReqOpt;\r
+ UINT8 OptBuf[10];\r
\r
// Downloaded file can be large. BS.AllocatePages() is more faster\r
// than AllocatePool() and avoid fragmentation.\r
Mtftp4Token.Buffer = Buffer;\r
Mtftp4Token.CheckPacket = CheckPacket;\r
Mtftp4Token.Context = (VOID*)TftpContext;\r
+ if (BlockSize != MTFTP_DEFAULT_BLKSIZE) {\r
+ ReqOpt.OptionStr = (UINT8 *) "blksize";\r
+ AsciiSPrint ((CHAR8 *)OptBuf, sizeof (OptBuf), "%d", BlockSize);\r
+ ReqOpt.ValueStr = OptBuf;\r
+\r
+ Mtftp4Token.OptionCount = 1;\r
+ Mtftp4Token.OptionList = &ReqOpt;\r
+ }\r
\r
ShellPrintHiiEx (\r
-1, -1, NULL, STRING_TOKEN (STR_TFTP_DOWNLOADING),\r
**/\r
STATIC\r
EFI_STATUS\r
+EFIAPI\r
CheckPacket (\r
IN EFI_MTFTP4_PROTOCOL *This,\r
IN EFI_MTFTP4_TOKEN *Token,\r
{\r
DOWNLOAD_CONTEXT *Context;\r
CHAR16 Progress[TFTP_PROGRESS_MESSAGE_SIZE];\r
- UINT64 NbOfKb;\r
+ UINTN NbOfKb;\r
UINTN Index;\r
UINTN LastStep;\r
UINTN Step;\r
+ EFI_STATUS Status;\r
\r
if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) {\r
return EFI_SUCCESS;\r
NbOfKb = Context->DownloadedNbOfBytes / 1024;\r
\r
Progress[0] = L'\0';\r
- LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) /\r
- Context->FileSize;\r
- Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) /\r
- Context->FileSize;\r
+ LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;\r
+ Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;\r
+\r
if (Step <= LastStep) {\r
return EFI_SUCCESS;\r
}\r
\r
ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete);\r
\r
- StrCpy (Progress, mTftpProgressFrame);\r
+ Status = StrCpyS (Progress, TFTP_PROGRESS_MESSAGE_SIZE, mTftpProgressFrame);\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
for (Index = 1; Index < Step; Index++) {\r
Progress[Index] = L'=';\r
}\r