]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
ShellPkg/TftpDynamicCommand: Fix the potentially uninitialized local variable used.
[mirror_edk2.git] / ShellPkg / DynamicCommand / TftpDynamicCommand / Tftp.c
index 8569c966ddf3be4c7e4dd039f852429c3588111c..d4391b9f33cd27adff0925ffec755aaf2da34740 100644 (file)
@@ -2,7 +2,7 @@
   The implementation for the 'tftp' Shell command.\r
 \r
   Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r
-  Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved. <BR>\r
+  Copyright (c) 2015 - 2018, 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
@@ -50,8 +50,8 @@ STATIC CONST CHAR16 mTftpProgressDelete[] = L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b
   @return     TRUE      The value was returned.\r
   @return     FALSE     A parsing error occured.\r
 **/\r
-STATIC \r
-BOOLEAN \r
+STATIC\r
+BOOLEAN\r
 StringToUint16 (\r
   IN   CONST CHAR16  *ValueStr,\r
   OUT  UINT16        *Value\r
@@ -64,7 +64,7 @@ StringToUint16 (
   @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_CONFIG2_INTERFACE_INFO_NAME_LENGTH \r
+                                 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH\r
                                  double byte wide.\r
 \r
   @return  EFI_SUCCESS  The name of the NIC was returned.\r
@@ -75,8 +75,8 @@ StringToUint16 (
                         Managed Network Protocol could not be\r
                         read.\r
 **/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
 GetNicName (\r
   IN   EFI_HANDLE  ControllerHandle,\r
   IN   UINTN       NicNumber,\r
@@ -102,8 +102,8 @@ GetNicName (
   @return  Others       Either the creation of the child or the opening\r
                         of the protocol failed.\r
 **/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
 CreateServiceChildAndOpenProtocol (\r
   IN   EFI_HANDLE  ControllerHandle,\r
   IN   EFI_GUID    *ServiceBindingProtocolGuid,\r
@@ -124,8 +124,8 @@ CreateServiceChildAndOpenProtocol (
   @param[in]  ChildHandle                 Handle of the child to be destroyed.\r
 \r
 **/\r
-STATIC \r
-VOID \r
+STATIC\r
+VOID\r
 CloseProtocolAndDestroyServiceChild (\r
   IN  EFI_HANDLE  ControllerHandle,\r
   IN  EFI_GUID    *ServiceBindingProtocolGuid,\r
@@ -148,8 +148,8 @@ CloseProtocolAndDestroyServiceChild (
                             (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)\r
                             or error when parsing the response of the server.\r
 **/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
 GetFileSize (\r
   IN   EFI_MTFTP4_PROTOCOL  *Mtftp4,\r
   IN   CONST CHAR8          *FilePath,\r
@@ -175,14 +175,15 @@ GetFileSize (
                                  (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).\r
 \r
 **/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
 DownloadFile (\r
   IN   EFI_MTFTP4_PROTOCOL  *Mtftp4,\r
   IN   CONST CHAR16         *FilePath,\r
   IN   CONST CHAR8          *AsciiFilePath,\r
   IN   UINTN                FileSize,\r
   IN   UINT16               BlockSize,\r
+  IN   UINT16               WindowSize,\r
   OUT  VOID                 **Data\r
   );\r
 \r
@@ -198,8 +199,8 @@ DownloadFile (
   @retval  EFI_SUCCESS  All packets are accepted.\r
 \r
 **/\r
-STATIC \r
-EFI_STATUS \r
+STATIC\r
+EFI_STATUS\r
 EFIAPI\r
 CheckPacket (\r
   IN EFI_MTFTP4_PROTOCOL  *This,\r
@@ -227,6 +228,7 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
   {L"-c", TypeValue},\r
   {L"-t", TypeValue},\r
   {L"-s", TypeValue},\r
+  {L"-w", TypeValue},\r
   {NULL , TypeMax}\r
   };\r
 \r
@@ -239,7 +241,17 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 ///\r
 #define MTFTP_MIN_BLKSIZE          8\r
 #define MTFTP_MAX_BLKSIZE          65464\r
-\r
+///\r
+/// The default windowsize (1) of tftp.\r
+///\r
+#define MTFTP_DEFAULT_WINDOWSIZE   1\r
+///\r
+/// The valid range of window size option.\r
+/// Note that: RFC 7440 does not mention max window size value, but for the\r
+/// stability reason, the value is limited to 64.\r
+///\r
+#define MTFTP_MIN_WINDOWSIZE       1\r
+#define MTFTP_MAX_WINDOWSIZE       64\r
 \r
 /**\r
   Function for 'tftp' command.\r
@@ -288,6 +300,7 @@ RunTftp (
   VOID                    *Data;\r
   SHELL_FILE_HANDLE       FileHandle;\r
   UINT16                  BlockSize;\r
+  UINT16                  WindowSize;\r
 \r
   ShellStatus         = SHELL_INVALID_PARAMETER;\r
   ProblemParam        = NULL;\r
@@ -297,6 +310,7 @@ RunTftp (
   FileSize            = 0;\r
   DataSize            = 0;\r
   BlockSize           = MTFTP_DEFAULT_BLKSIZE;\r
+  WindowSize          = MTFTP_DEFAULT_WINDOWSIZE;\r
 \r
   //\r
   // Initialize the Shell library (we must be in non-auto-init...)\r
@@ -436,6 +450,20 @@ RunTftp (
     }\r
   }\r
 \r
+  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-w");\r
+  if (ValueStr != NULL) {\r
+    if (!StringToUint16 (ValueStr, &WindowSize)) {\r
+      goto Error;\r
+    }\r
+    if (WindowSize < MTFTP_MIN_WINDOWSIZE || WindowSize > MTFTP_MAX_WINDOWSIZE) {\r
+      ShellPrintHiiEx (\r
+        -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
+        mTftpHiiHandle, L"tftp", ValueStr\r
+      );\r
+      goto Error;\r
+    }\r
+  }\r
+\r
   //\r
   // Locate all MTFTP4 Service Binding protocols\r
   //\r
@@ -510,7 +538,7 @@ RunTftp (
       goto NextHandle;\r
     }\r
 \r
-    Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, &Data);\r
+    Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize, &Data);\r
     if (EFI_ERROR (Status)) {\r
       ShellPrintHiiEx (\r
         -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),\r
@@ -519,6 +547,8 @@ RunTftp (
       goto NextHandle;\r
     }\r
 \r
+    DataSize = FileSize;\r
+\r
     if (!EFI_ERROR (ShellFileExists (LocalFilePath))) {\r
       ShellDeleteFileByName (LocalFilePath);\r
     }\r
@@ -539,7 +569,6 @@ RunTftp (
       goto NextHandle;\r
     }\r
 \r
-    DataSize = FileSize;\r
     Status = ShellWriteFile (FileHandle, &FileSize, Data);\r
     if (!EFI_ERROR (Status)) {\r
       ShellStatus = SHELL_SUCCESS;\r
@@ -623,7 +652,7 @@ StringToUint16 (
   @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_CONFIG2_INTERFACE_INFO_NAME_LENGTH \r
+                                 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH\r
                                  double byte wide.\r
 \r
   @return  EFI_SUCCESS  The name of the NIC was returned.\r
@@ -895,6 +924,7 @@ DownloadFile (
   IN   CONST CHAR8          *AsciiFilePath,\r
   IN   UINTN                FileSize,\r
   IN   UINT16               BlockSize,\r
+  IN   UINT16               WindowSize,\r
   OUT  VOID                 **Data\r
   )\r
 {\r
@@ -903,8 +933,10 @@ DownloadFile (
   VOID                  *Buffer;\r
   DOWNLOAD_CONTEXT      *TftpContext;\r
   EFI_MTFTP4_TOKEN      Mtftp4Token;\r
-  EFI_MTFTP4_OPTION     ReqOpt;\r
-  UINT8                 OptBuf[10];\r
+  UINT8                 BlksizeBuf[10];\r
+  UINT8                 WindowsizeBuf[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
@@ -931,19 +963,30 @@ DownloadFile (
   TftpContext->DownloadedNbOfBytes   = 0;\r
   TftpContext->LastReportedNbOfBytes = 0;\r
 \r
-  ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));\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
+  Mtftp4Token.OptionList  = AllocatePool (sizeof (EFI_MTFTP4_OPTION) * 2);\r
+  if (Mtftp4Token.OptionList == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Error;\r
+  }\r
+\r
   if (BlockSize != MTFTP_DEFAULT_BLKSIZE) {\r
-    ReqOpt.OptionStr = (UINT8 *) "blksize";\r
-    AsciiSPrint ((CHAR8 *)OptBuf, sizeof (OptBuf), "%d", BlockSize);\r
-    ReqOpt.ValueStr  = OptBuf;\r
+    Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *) "blksize";\r
+    AsciiSPrint ((CHAR8 *) BlksizeBuf, sizeof (BlksizeBuf), "%d", BlockSize);\r
+    Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr  = BlksizeBuf;\r
+    Mtftp4Token.OptionCount ++;\r
+  }\r
 \r
-    Mtftp4Token.OptionCount = 1;\r
-    Mtftp4Token.OptionList  = &ReqOpt;\r
+  if (WindowSize != MTFTP_DEFAULT_WINDOWSIZE) {\r
+    Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *) "windowsize";\r
+    AsciiSPrint ((CHAR8 *) WindowsizeBuf, sizeof (WindowsizeBuf), "%d", WindowSize);\r
+    Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr  = WindowsizeBuf;\r
+    Mtftp4Token.OptionCount ++;\r
   }\r
 \r
   ShellPrintHiiEx (\r
@@ -959,10 +1002,14 @@ DownloadFile (
 \r
 Error :\r
 \r
-  if (TftpContext == NULL) {\r
+  if (TftpContext != NULL) {\r
     FreePool (TftpContext);\r
   }\r
 \r
+  if (Mtftp4Token.OptionList != NULL) {\r
+    FreePool (Mtftp4Token.OptionList);\r
+  }\r
+\r
   if (EFI_ERROR (Status)) {\r
     gBS->FreePages (PagesAddress, EFI_SIZE_TO_PAGES (FileSize));\r
     return Status;\r