]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcMtftp.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcMtftp.c
index 270190d42e4b75f6bbc1c34bf1e955d775501ef1..3ac9c7a8aafe6c4f0b6ee67212c75cb29eb8d36e 100644 (file)
@@ -1,28 +1,22 @@
 /** @file\r
   Functions implementation related with Mtftp for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<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
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "PxeBcImpl.h"\r
 \r
-CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {\r
+CHAR8  *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {\r
   "blksize",\r
   "timeout",\r
   "tsize",\r
-  "multicast"\r
+  "multicast",\r
+  "windowsize"\r
 };\r
 \r
-\r
 /**\r
   This is a callback function when packets are received or transmitted in Mtftp driver.\r
 \r
@@ -44,30 +38,30 @@ CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {
 EFI_STATUS\r
 EFIAPI\r
 PxeBcMtftp6CheckPacket (\r
-  IN EFI_MTFTP6_PROTOCOL              *This,\r
-  IN EFI_MTFTP6_TOKEN                 *Token,\r
-  IN UINT16                           PacketLen,\r
-  IN EFI_MTFTP6_PACKET                *Packet\r
+  IN EFI_MTFTP6_PROTOCOL  *This,\r
+  IN EFI_MTFTP6_TOKEN     *Token,\r
+  IN UINT16               PacketLen,\r
+  IN EFI_MTFTP6_PACKET    *Packet\r
   )\r
 {\r
-  PXEBC_PRIVATE_DATA                  *Private;\r
-  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;\r
-  EFI_STATUS                          Status;\r
+  PXEBC_PRIVATE_DATA                   *Private;\r
+  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  *Callback;\r
+  EFI_STATUS                           Status;\r
 \r
-  Private   = (PXEBC_PRIVATE_DATA *) Token->Context;\r
-  Callback  = Private->PxeBcCallback;\r
-  Status    = EFI_SUCCESS;\r
+  Private  = (PXEBC_PRIVATE_DATA *)Token->Context;\r
+  Callback = Private->PxeBcCallback;\r
+  Status   = EFI_SUCCESS;\r
 \r
   if (Packet->OpCode == EFI_MTFTP6_OPCODE_ERROR) {\r
     //\r
     // Store the tftp error message into mode data and set the received flag.\r
     //\r
     Private->Mode.TftpErrorReceived   = TRUE;\r
-    Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
+    Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;\r
     AsciiStrnCpyS (\r
       Private->Mode.TftpError.ErrorString,\r
       PXE_MTFTP_ERROR_STRING_LENGTH,\r
-      (CHAR8 *) Packet->Error.ErrorMessage,\r
+      (CHAR8 *)Packet->Error.ErrorMessage,\r
       PXE_MTFTP_ERROR_STRING_LENGTH - 1\r
       );\r
     Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';\r
@@ -78,12 +72,12 @@ PxeBcMtftp6CheckPacket (
     // Callback to user if has when received any tftp packet.\r
     //\r
     Status = Callback->Callback (\r
-                        Callback,\r
-                        Private->Function,\r
-                        TRUE,\r
-                        PacketLen,\r
-                        (EFI_PXE_BASE_CODE_PACKET *) Packet\r
-                        );\r
+                         Callback,\r
+                         Private->Function,\r
+                         TRUE,\r
+                         PacketLen,\r
+                         (EFI_PXE_BASE_CODE_PACKET *)Packet\r
+                         );\r
     if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
       //\r
       // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.\r
@@ -100,7 +94,6 @@ PxeBcMtftp6CheckPacket (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is to get the size of a file using Tftp.\r
 \r
@@ -108,31 +101,34 @@ PxeBcMtftp6CheckPacket (
   @param[in]      Config         Pointer to EFI_MTFTP6_CONFIG_DATA.\r
   @param[in]      Filename       Pointer to boot file name.\r
   @param[in]      BlockSize      Pointer to required block size.\r
+  @param[in]      WindowSize     Pointer to required window size.\r
   @param[in, out] BufferSize     Pointer to buffer size.\r
 \r
-  @retval EFI_SUCCESS        Sucessfully obtained the size of file.\r
-  @retval EFI_NOT_FOUND      Parse the tftp ptions failed.\r
+  @retval EFI_SUCCESS        Successfully obtained the size of file.\r
+  @retval EFI_NOT_FOUND      Parse the tftp options failed.\r
   @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.\r
   @retval Others             Has not obtained the size of the file.\r
 \r
 **/\r
 EFI_STATUS\r
 PxeBcMtftp6GetFileSize (\r
-  IN     PXEBC_PRIVATE_DATA           *Private,\r
-  IN     EFI_MTFTP6_CONFIG_DATA       *Config,\r
-  IN     UINT8                        *Filename,\r
-  IN     UINTN                        *BlockSize,\r
-  IN OUT UINT64                       *BufferSize\r
+  IN     PXEBC_PRIVATE_DATA      *Private,\r
+  IN     EFI_MTFTP6_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINTN                   *WindowSize,\r
+  IN OUT UINT64                  *BufferSize\r
   )\r
 {\r
-  EFI_MTFTP6_PROTOCOL                 *Mtftp6;\r
-  EFI_MTFTP6_OPTION                   ReqOpt[2];\r
-  EFI_MTFTP6_PACKET                   *Packet;\r
-  EFI_MTFTP6_OPTION                   *Option;\r
-  UINT32                              PktLen;\r
-  UINT8                               OptBuf[128];\r
-  UINT32                              OptCnt;\r
-  EFI_STATUS                          Status;\r
+  EFI_MTFTP6_PROTOCOL  *Mtftp6;\r
+  EFI_MTFTP6_OPTION    ReqOpt[3];\r
+  EFI_MTFTP6_PACKET    *Packet;\r
+  EFI_MTFTP6_OPTION    *Option;\r
+  UINT32               PktLen;\r
+  UINT8                OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];\r
+  UINTN                OptBufSize;\r
+  UINT32               OptCnt;\r
+  EFI_STATUS           Status;\r
 \r
   *BufferSize               = 0;\r
   Status                    = EFI_DEVICE_ERROR;\r
@@ -140,6 +136,7 @@ PxeBcMtftp6GetFileSize (
   Packet                    = NULL;\r
   Option                    = NULL;\r
   PktLen                    = 0;\r
+  OptBufSize                = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;\r
   OptCnt                    = 1;\r
   Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
 \r
@@ -151,14 +148,23 @@ PxeBcMtftp6GetFileSize (
   //\r
   // Build the required options for get info.\r
   //\r
-  ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
-  PxeBcUintnToAscDec (0, OptBuf, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
-  ReqOpt[0].ValueStr  = OptBuf;\r
+  ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
+  PxeBcUintnToAscDec (0, OptBuf, OptBufSize);\r
+  ReqOpt[0].ValueStr = OptBuf;\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[1].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
-    ReqOpt[1].ValueStr  = (UINT8 *) (ReqOpt[0].ValueStr + AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1);\r
-    PxeBcUintnToAscDec (*BlockSize, ReqOpt[1].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX - (AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1));\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);\r
+    OptCnt++;\r
+  }\r
+\r
+  if (WindowSize != NULL) {\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);\r
     OptCnt++;\r
   }\r
 \r
@@ -167,7 +173,7 @@ PxeBcMtftp6GetFileSize (
                      NULL,\r
                      Filename,\r
                      NULL,\r
-                     (UINT8) OptCnt,\r
+                     (UINT8)OptCnt,\r
                      ReqOpt,\r
                      &PktLen,\r
                      &Packet\r
@@ -178,15 +184,16 @@ PxeBcMtftp6GetFileSize (
       // Store the tftp error message into mode data and set the received flag.\r
       //\r
       Private->Mode.TftpErrorReceived   = TRUE;\r
-      Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
+      Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;\r
       AsciiStrnCpyS (\r
         Private->Mode.TftpError.ErrorString,\r
         PXE_MTFTP_ERROR_STRING_LENGTH,\r
-        (CHAR8 *) Packet->Error.ErrorMessage,\r
+        (CHAR8 *)Packet->Error.ErrorMessage,\r
         PXE_MTFTP_ERROR_STRING_LENGTH - 1\r
         );\r
       Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';\r
     }\r
+\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -198,7 +205,7 @@ PxeBcMtftp6GetFileSize (
                      Mtftp6,\r
                      PktLen,\r
                      Packet,\r
-                     (UINT32 *) &OptCnt,\r
+                     (UINT32 *)&OptCnt,\r
                      &Option\r
                      );\r
   if (EFI_ERROR (Status)) {\r
@@ -210,24 +217,26 @@ PxeBcMtftp6GetFileSize (
   //\r
   Status = EFI_NOT_FOUND;\r
   while (OptCnt != 0) {\r
-    if (AsciiStrnCmp ((CHAR8 *) Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {\r
-      *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *) (Option[OptCnt - 1].ValueStr));\r
+    if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {\r
+      *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));\r
       Status      = EFI_SUCCESS;\r
     }\r
+\r
     OptCnt--;\r
   }\r
+\r
   FreePool (Option);\r
 \r
 ON_ERROR:\r
   if (Packet != NULL) {\r
     FreePool (Packet);\r
   }\r
+\r
   Mtftp6->Configure (Mtftp6, NULL);\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is to get data of a file using Tftp.\r
 \r
@@ -235,6 +244,7 @@ ON_ERROR:
   @param[in]      Config         Pointer to EFI_MTFTP6_CONFIG_DATA.\r
   @param[in]      Filename       Pointer to boot file name.\r
   @param[in]      BlockSize      Pointer to required block size.\r
+  @param[in]      WindowSize     Pointer to required window size.\r
   @param[in]      BufferPtr      Pointer to buffer.\r
   @param[in, out] BufferSize     Pointer to buffer size.\r
   @param[in]      DontUseBuffer  Indicates whether with a receive buffer.\r
@@ -246,21 +256,23 @@ ON_ERROR:
 **/\r
 EFI_STATUS\r
 PxeBcMtftp6ReadFile (\r
-  IN    PXEBC_PRIVATE_DATA            *Private,\r
-  IN     EFI_MTFTP6_CONFIG_DATA       *Config,\r
-  IN     UINT8                        *Filename,\r
-  IN     UINTN                        *BlockSize,\r
-  IN     UINT8                        *BufferPtr,\r
-  IN OUT UINT64                       *BufferSize,\r
-  IN     BOOLEAN                      DontUseBuffer\r
+  IN    PXEBC_PRIVATE_DATA       *Private,\r
+  IN     EFI_MTFTP6_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINTN                   *WindowSize,\r
+  IN     UINT8                   *BufferPtr,\r
+  IN OUT UINT64                  *BufferSize,\r
+  IN     BOOLEAN                 DontUseBuffer\r
   )\r
 {\r
-  EFI_MTFTP6_PROTOCOL                 *Mtftp6;\r
-  EFI_MTFTP6_TOKEN                    Token;\r
-  EFI_MTFTP6_OPTION                   ReqOpt[1];\r
-  UINT32                              OptCnt;\r
-  UINT8                               OptBuf[128];\r
-  EFI_STATUS                          Status;\r
+  EFI_MTFTP6_PROTOCOL  *Mtftp6;\r
+  EFI_MTFTP6_TOKEN     Token;\r
+  EFI_MTFTP6_OPTION    ReqOpt[2];\r
+  UINT32               OptCnt;\r
+  UINT8                BlksizeBuf[10];\r
+  UINT8                WindowsizeBuf[10];\r
+  EFI_STATUS           Status;\r
 \r
   Status                    = EFI_DEVICE_ERROR;\r
   Mtftp6                    = Private->Mtftp6;\r
@@ -273,26 +285,33 @@ PxeBcMtftp6ReadFile (
   }\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
-    ReqOpt[0].ValueStr  = OptBuf;\r
-    PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;\r
+    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));\r
+    OptCnt++;\r
+  }\r
+\r
+  if (WindowSize != NULL) {\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;\r
+    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));\r
     OptCnt++;\r
   }\r
 \r
-  Token.Event         = NULL;\r
-  Token.OverrideData  = NULL;\r
-  Token.Filename      = Filename;\r
-  Token.ModeStr       = NULL;\r
-  Token.OptionCount   = OptCnt;\r
-  Token.OptionList    = ReqOpt;\r
-  Token.Context       = Private;\r
+  Token.Event        = NULL;\r
+  Token.OverrideData = NULL;\r
+  Token.Filename     = Filename;\r
+  Token.ModeStr      = NULL;\r
+  Token.OptionCount  = OptCnt;\r
+  Token.OptionList   = ReqOpt;\r
+  Token.Context      = Private;\r
 \r
   if (DontUseBuffer) {\r
-    Token.BufferSize  = 0;\r
-    Token.Buffer      = NULL;\r
+    Token.BufferSize = 0;\r
+    Token.Buffer     = NULL;\r
   } else {\r
-    Token.BufferSize  = *BufferSize;\r
-    Token.Buffer      = BufferPtr;\r
+    Token.BufferSize = *BufferSize;\r
+    Token.Buffer     = BufferPtr;\r
   }\r
 \r
   Token.CheckPacket     = PxeBcMtftp6CheckPacket;\r
@@ -310,7 +329,6 @@ PxeBcMtftp6ReadFile (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is used to write the data of a file using Tftp.\r
 \r
@@ -329,21 +347,21 @@ PxeBcMtftp6ReadFile (
 **/\r
 EFI_STATUS\r
 PxeBcMtftp6WriteFile (\r
-  IN     PXEBC_PRIVATE_DATA           *Private,\r
-  IN     EFI_MTFTP6_CONFIG_DATA       *Config,\r
-  IN     UINT8                        *Filename,\r
-  IN     BOOLEAN                      Overwrite,\r
-  IN     UINTN                        *BlockSize,\r
-  IN     UINT8                        *BufferPtr,\r
-  IN OUT UINT64                       *BufferSize\r
+  IN     PXEBC_PRIVATE_DATA      *Private,\r
+  IN     EFI_MTFTP6_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     BOOLEAN                 Overwrite,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINT8                   *BufferPtr,\r
+  IN OUT UINT64                  *BufferSize\r
   )\r
 {\r
-  EFI_MTFTP6_PROTOCOL                 *Mtftp6;\r
-  EFI_MTFTP6_TOKEN                    Token;\r
-  EFI_MTFTP6_OPTION                   ReqOpt[1];\r
-  UINT32                              OptCnt;\r
-  UINT8                               OptBuf[128];\r
-  EFI_STATUS                          Status;\r
+  EFI_MTFTP6_PROTOCOL  *Mtftp6;\r
+  EFI_MTFTP6_TOKEN     Token;\r
+  EFI_MTFTP6_OPTION    ReqOpt[1];\r
+  UINT32               OptCnt;\r
+  UINT8                OptBuf[128];\r
+  EFI_STATUS           Status;\r
 \r
   Status                    = EFI_DEVICE_ERROR;\r
   Mtftp6                    = Private->Mtftp6;\r
@@ -356,7 +374,7 @@ PxeBcMtftp6WriteFile (
   }\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
     ReqOpt[0].ValueStr  = OptBuf;\r
     PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
     OptCnt++;\r
@@ -385,7 +403,6 @@ PxeBcMtftp6WriteFile (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is to read the data (file) from a directory using Tftp.\r
 \r
@@ -393,6 +410,7 @@ PxeBcMtftp6WriteFile (
   @param[in]       Config         Pointer to EFI_MTFTP6_CONFIG_DATA.\r
   @param[in]       Filename       Pointer to boot file name.\r
   @param[in]       BlockSize      Pointer to required block size.\r
+  @param[in]       WindowSize     Pointer to required window size.\r
   @param[in]       BufferPtr      Pointer to buffer.\r
   @param[in, out]  BufferSize     Pointer to buffer size.\r
   @param[in]       DontUseBuffer  Indicates whether to use a receive buffer.\r
@@ -404,21 +422,23 @@ PxeBcMtftp6WriteFile (
 **/\r
 EFI_STATUS\r
 PxeBcMtftp6ReadDirectory (\r
-  IN     PXEBC_PRIVATE_DATA            *Private,\r
-  IN     EFI_MTFTP6_CONFIG_DATA        *Config,\r
-  IN     UINT8                         *Filename,\r
-  IN     UINTN                         *BlockSize,\r
-  IN     UINT8                         *BufferPtr,\r
-  IN OUT UINT64                        *BufferSize,\r
-  IN     BOOLEAN                       DontUseBuffer\r
+  IN     PXEBC_PRIVATE_DATA      *Private,\r
+  IN     EFI_MTFTP6_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINTN                   *WindowSize,\r
+  IN     UINT8                   *BufferPtr,\r
+  IN OUT UINT64                  *BufferSize,\r
+  IN     BOOLEAN                 DontUseBuffer\r
   )\r
 {\r
-  EFI_MTFTP6_PROTOCOL                  *Mtftp6;\r
-  EFI_MTFTP6_TOKEN                     Token;\r
-  EFI_MTFTP6_OPTION                    ReqOpt[1];\r
-  UINT32                               OptCnt;\r
-  UINT8                                OptBuf[128];\r
-  EFI_STATUS                           Status;\r
+  EFI_MTFTP6_PROTOCOL  *Mtftp6;\r
+  EFI_MTFTP6_TOKEN     Token;\r
+  EFI_MTFTP6_OPTION    ReqOpt[2];\r
+  UINT32               OptCnt;\r
+  UINT8                BlksizeBuf[10];\r
+  UINT8                WindowsizeBuf[10];\r
+  EFI_STATUS           Status;\r
 \r
   Status                    = EFI_DEVICE_ERROR;\r
   Mtftp6                    = Private->Mtftp6;\r
@@ -431,26 +451,33 @@ PxeBcMtftp6ReadDirectory (
   }\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
-    ReqOpt[0].ValueStr  = OptBuf;\r
-    PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;\r
+    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));\r
     OptCnt++;\r
   }\r
 \r
-  Token.Event         = NULL;\r
-  Token.OverrideData  = NULL;\r
-  Token.Filename      = Filename;\r
-  Token.ModeStr       = NULL;\r
-  Token.OptionCount   = OptCnt;\r
-  Token.OptionList    = ReqOpt;\r
-  Token.Context       = Private;\r
+  if (WindowSize != NULL) {\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;\r
+    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));\r
+    OptCnt++;\r
+  }\r
+\r
+  Token.Event        = NULL;\r
+  Token.OverrideData = NULL;\r
+  Token.Filename     = Filename;\r
+  Token.ModeStr      = NULL;\r
+  Token.OptionCount  = OptCnt;\r
+  Token.OptionList   = ReqOpt;\r
+  Token.Context      = Private;\r
 \r
   if (DontUseBuffer) {\r
-    Token.BufferSize  = 0;\r
-    Token.Buffer      = NULL;\r
+    Token.BufferSize = 0;\r
+    Token.Buffer     = NULL;\r
   } else {\r
-    Token.BufferSize  = *BufferSize;\r
-    Token.Buffer      = BufferPtr;\r
+    Token.BufferSize = *BufferSize;\r
+    Token.Buffer     = BufferPtr;\r
   }\r
 \r
   Token.CheckPacket     = PxeBcMtftp6CheckPacket;\r
@@ -468,7 +495,6 @@ PxeBcMtftp6ReadDirectory (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This is a callback function when packets are received or transmitted in Mtftp driver.\r
 \r
@@ -483,37 +509,37 @@ PxeBcMtftp6ReadDirectory (
   @param[in]  PacketLen      Length of EFI_MTFTP4_PACKET.\r
   @param[in]  Packet         Pointer to EFI_MTFTP4_PACKET to be checked.\r
 \r
-  @retval EFI_SUCCESS    The current operation succeeeded.\r
+  @retval EFI_SUCCESS    The current operation succeeded.\r
   @retval EFI_ABORTED    Abort the current transfer process.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 PxeBcMtftp4CheckPacket (\r
-  IN EFI_MTFTP4_PROTOCOL        *This,\r
-  IN EFI_MTFTP4_TOKEN           *Token,\r
-  IN UINT16                     PacketLen,\r
-  IN EFI_MTFTP4_PACKET          *Packet\r
+  IN EFI_MTFTP4_PROTOCOL  *This,\r
+  IN EFI_MTFTP4_TOKEN     *Token,\r
+  IN UINT16               PacketLen,\r
+  IN EFI_MTFTP4_PACKET    *Packet\r
   )\r
 {\r
-  PXEBC_PRIVATE_DATA                  *Private;\r
-  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;\r
-  EFI_STATUS                          Status;\r
+  PXEBC_PRIVATE_DATA                   *Private;\r
+  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  *Callback;\r
+  EFI_STATUS                           Status;\r
 \r
-  Private   = (PXEBC_PRIVATE_DATA *) Token->Context;\r
-  Callback  = Private->PxeBcCallback;\r
-  Status    = EFI_SUCCESS;\r
+  Private  = (PXEBC_PRIVATE_DATA *)Token->Context;\r
+  Callback = Private->PxeBcCallback;\r
+  Status   = EFI_SUCCESS;\r
 \r
   if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {\r
     //\r
     // Store the tftp error message into mode data and set the received flag.\r
     //\r
     Private->Mode.TftpErrorReceived   = TRUE;\r
-    Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
+    Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;\r
     AsciiStrnCpyS (\r
       Private->Mode.TftpError.ErrorString,\r
       PXE_MTFTP_ERROR_STRING_LENGTH,\r
-      (CHAR8 *) Packet->Error.ErrorMessage,\r
+      (CHAR8 *)Packet->Error.ErrorMessage,\r
       PXE_MTFTP_ERROR_STRING_LENGTH - 1\r
       );\r
     Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';\r
@@ -524,12 +550,12 @@ PxeBcMtftp4CheckPacket (
     // Callback to user if has when received any tftp packet.\r
     //\r
     Status = Callback->Callback (\r
-                        Callback,\r
-                        Private->Function,\r
-                        TRUE,\r
-                        PacketLen,\r
-                        (EFI_PXE_BASE_CODE_PACKET *) Packet\r
-                        );\r
+                         Callback,\r
+                         Private->Function,\r
+                         TRUE,\r
+                         PacketLen,\r
+                         (EFI_PXE_BASE_CODE_PACKET *)Packet\r
+                         );\r
     if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
       //\r
       // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.\r
@@ -546,7 +572,6 @@ PxeBcMtftp4CheckPacket (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is to get size of a file using Tftp.\r
 \r
@@ -554,6 +579,7 @@ PxeBcMtftp4CheckPacket (
   @param[in]      Config         Pointer to EFI_MTFTP4_CONFIG_DATA.\r
   @param[in]      Filename       Pointer to boot file name.\r
   @param[in]      BlockSize      Pointer to required block size.\r
+  @param[in]      WindowSize     Pointer to required window size.\r
   @param[in, out] BufferSize     Pointer to buffer size.\r
 \r
   @retval EFI_SUCCESS        Successfully obtained the size of file.\r
@@ -564,21 +590,23 @@ PxeBcMtftp4CheckPacket (
 **/\r
 EFI_STATUS\r
 PxeBcMtftp4GetFileSize (\r
-  IN     PXEBC_PRIVATE_DATA         *Private,\r
-  IN     EFI_MTFTP4_CONFIG_DATA     *Config,\r
-  IN     UINT8                      *Filename,\r
-  IN     UINTN                      *BlockSize,\r
-  IN OUT UINT64                     *BufferSize\r
+  IN     PXEBC_PRIVATE_DATA      *Private,\r
+  IN     EFI_MTFTP4_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINTN                   *WindowSize,\r
+  IN OUT UINT64                  *BufferSize\r
   )\r
 {\r
-  EFI_MTFTP4_PROTOCOL *Mtftp4;\r
-  EFI_MTFTP4_OPTION   ReqOpt[2];\r
-  EFI_MTFTP4_PACKET   *Packet;\r
-  EFI_MTFTP4_OPTION   *Option;\r
-  UINT32              PktLen;\r
-  UINT8               OptBuf[128];\r
-  UINT32              OptCnt;\r
-  EFI_STATUS          Status;\r
+  EFI_MTFTP4_PROTOCOL  *Mtftp4;\r
+  EFI_MTFTP4_OPTION    ReqOpt[3];\r
+  EFI_MTFTP4_PACKET    *Packet;\r
+  EFI_MTFTP4_OPTION    *Option;\r
+  UINT32               PktLen;\r
+  UINT8                OptBuf[PXE_MTFTP_OPTBUF_MAXNUM_INDEX];\r
+  UINTN                OptBufSize;\r
+  UINT32               OptCnt;\r
+  EFI_STATUS           Status;\r
 \r
   *BufferSize               = 0;\r
   Status                    = EFI_DEVICE_ERROR;\r
@@ -586,6 +614,7 @@ PxeBcMtftp4GetFileSize (
   Packet                    = NULL;\r
   Option                    = NULL;\r
   PktLen                    = 0;\r
+  OptBufSize                = PXE_MTFTP_OPTBUF_MAXNUM_INDEX;\r
   OptCnt                    = 1;\r
   Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
 \r
@@ -597,14 +626,23 @@ PxeBcMtftp4GetFileSize (
   //\r
   // Build the required options for get info.\r
   //\r
-  ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
-  PxeBcUintnToAscDec (0, OptBuf, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
-  ReqOpt[0].ValueStr  = OptBuf;\r
+  ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
+  PxeBcUintnToAscDec (0, OptBuf, OptBufSize);\r
+  ReqOpt[0].ValueStr = OptBuf;\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[1].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
-    ReqOpt[1].ValueStr  = (UINT8 *) (ReqOpt[0].ValueStr + AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1);\r
-    PxeBcUintnToAscDec (*BlockSize, ReqOpt[1].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX - (AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1));\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, OptBufSize);\r
+    OptCnt++;\r
+  }\r
+\r
+  if (WindowSize != NULL) {\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = (UINT8 *)(ReqOpt[OptCnt-1].ValueStr + AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    OptBufSize              -= (AsciiStrLen ((CHAR8 *)ReqOpt[OptCnt-1].ValueStr) + 1);\r
+    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, OptBufSize);\r
     OptCnt++;\r
   }\r
 \r
@@ -613,7 +651,7 @@ PxeBcMtftp4GetFileSize (
                      NULL,\r
                      Filename,\r
                      NULL,\r
-                     (UINT8) OptCnt,\r
+                     (UINT8)OptCnt,\r
                      ReqOpt,\r
                      &PktLen,\r
                      &Packet\r
@@ -624,15 +662,16 @@ PxeBcMtftp4GetFileSize (
       // Store the tftp error message into mode data and set the received flag.\r
       //\r
       Private->Mode.TftpErrorReceived   = TRUE;\r
-      Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
+      Private->Mode.TftpError.ErrorCode = (UINT8)Packet->Error.ErrorCode;\r
       AsciiStrnCpyS (\r
         Private->Mode.TftpError.ErrorString,\r
         PXE_MTFTP_ERROR_STRING_LENGTH,\r
-        (CHAR8 *) Packet->Error.ErrorMessage,\r
+        (CHAR8 *)Packet->Error.ErrorMessage,\r
         PXE_MTFTP_ERROR_STRING_LENGTH - 1\r
         );\r
       Private->Mode.TftpError.ErrorString[PXE_MTFTP_ERROR_STRING_LENGTH - 1] = '\0';\r
     }\r
+\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -644,7 +683,7 @@ PxeBcMtftp4GetFileSize (
                      Mtftp4,\r
                      PktLen,\r
                      Packet,\r
-                     (UINT32 *) &OptCnt,\r
+                     (UINT32 *)&OptCnt,\r
                      &Option\r
                      );\r
   if (EFI_ERROR (Status)) {\r
@@ -656,24 +695,26 @@ PxeBcMtftp4GetFileSize (
   //\r
   Status = EFI_NOT_FOUND;\r
   while (OptCnt != 0) {\r
-    if (AsciiStrnCmp ((CHAR8 *) Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {\r
-      *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *) (Option[OptCnt - 1].ValueStr));\r
+    if (AsciiStrnCmp ((CHAR8 *)Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {\r
+      *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *)(Option[OptCnt - 1].ValueStr));\r
       Status      = EFI_SUCCESS;\r
     }\r
+\r
     OptCnt--;\r
   }\r
+\r
   FreePool (Option);\r
 \r
 ON_ERROR:\r
   if (Packet != NULL) {\r
     FreePool (Packet);\r
   }\r
+\r
   Mtftp4->Configure (Mtftp4, NULL);\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is to read the data of a file using Tftp.\r
 \r
@@ -681,6 +722,7 @@ ON_ERROR:
   @param[in]      Config         Pointer to EFI_MTFTP4_CONFIG_DATA.\r
   @param[in]      Filename       Pointer to boot file name.\r
   @param[in]      BlockSize      Pointer to required block size.\r
+  @param[in]      WindowSize     Pointer to required window size.\r
   @param[in]      BufferPtr      Pointer to buffer.\r
   @param[in, out] BufferSize     Pointer to buffer size.\r
   @param[in]      DontUseBuffer  Indicates whether to use a receive buffer.\r
@@ -692,21 +734,23 @@ ON_ERROR:
 **/\r
 EFI_STATUS\r
 PxeBcMtftp4ReadFile (\r
-  IN     PXEBC_PRIVATE_DATA         *Private,\r
-  IN     EFI_MTFTP4_CONFIG_DATA     *Config,\r
-  IN     UINT8                      *Filename,\r
-  IN     UINTN                      *BlockSize,\r
-  IN     UINT8                      *BufferPtr,\r
-  IN OUT UINT64                     *BufferSize,\r
-  IN     BOOLEAN                    DontUseBuffer\r
+  IN     PXEBC_PRIVATE_DATA      *Private,\r
+  IN     EFI_MTFTP4_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINTN                   *WindowSize,\r
+  IN     UINT8                   *BufferPtr,\r
+  IN OUT UINT64                  *BufferSize,\r
+  IN     BOOLEAN                 DontUseBuffer\r
   )\r
 {\r
-  EFI_MTFTP4_PROTOCOL *Mtftp4;\r
-  EFI_MTFTP4_TOKEN    Token;\r
-  EFI_MTFTP4_OPTION   ReqOpt[1];\r
-  UINT32              OptCnt;\r
-  UINT8               OptBuf[128];\r
-  EFI_STATUS          Status;\r
+  EFI_MTFTP4_PROTOCOL  *Mtftp4;\r
+  EFI_MTFTP4_TOKEN     Token;\r
+  EFI_MTFTP4_OPTION    ReqOpt[2];\r
+  UINT32               OptCnt;\r
+  UINT8                BlksizeBuf[10];\r
+  UINT8                WindowsizeBuf[10];\r
+  EFI_STATUS           Status;\r
 \r
   Status                    = EFI_DEVICE_ERROR;\r
   Mtftp4                    = Private->Mtftp4;\r
@@ -719,26 +763,33 @@ PxeBcMtftp4ReadFile (
   }\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
-    ReqOpt[0].ValueStr  = OptBuf;\r
-    PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;\r
+    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));\r
+    OptCnt++;\r
+  }\r
+\r
+  if (WindowSize != NULL) {\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;\r
+    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));\r
     OptCnt++;\r
   }\r
 \r
-  Token.Event         = NULL;\r
-  Token.OverrideData  = NULL;\r
-  Token.Filename      = Filename;\r
-  Token.ModeStr       = NULL;\r
-  Token.OptionCount   = OptCnt;\r
-  Token.OptionList    = ReqOpt;\r
-  Token.Context       = Private;\r
+  Token.Event        = NULL;\r
+  Token.OverrideData = NULL;\r
+  Token.Filename     = Filename;\r
+  Token.ModeStr      = NULL;\r
+  Token.OptionCount  = OptCnt;\r
+  Token.OptionList   = ReqOpt;\r
+  Token.Context      = Private;\r
 \r
   if (DontUseBuffer) {\r
-    Token.BufferSize  = 0;\r
-    Token.Buffer      = NULL;\r
+    Token.BufferSize = 0;\r
+    Token.Buffer     = NULL;\r
   } else {\r
-    Token.BufferSize  = *BufferSize;\r
-    Token.Buffer      = BufferPtr;\r
+    Token.BufferSize = *BufferSize;\r
+    Token.Buffer     = BufferPtr;\r
   }\r
 \r
   Token.CheckPacket     = PxeBcMtftp4CheckPacket;\r
@@ -756,7 +807,6 @@ PxeBcMtftp4ReadFile (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is to write the data of a file using Tftp.\r
 \r
@@ -775,34 +825,34 @@ PxeBcMtftp4ReadFile (
 **/\r
 EFI_STATUS\r
 PxeBcMtftp4WriteFile (\r
-  IN     PXEBC_PRIVATE_DATA         *Private,\r
-  IN     EFI_MTFTP4_CONFIG_DATA     *Config,\r
-  IN     UINT8                      *Filename,\r
-  IN     BOOLEAN                    Overwrite,\r
-  IN     UINTN                      *BlockSize,\r
-  IN     UINT8                      *BufferPtr,\r
-  IN OUT UINT64                     *BufferSize\r
+  IN     PXEBC_PRIVATE_DATA      *Private,\r
+  IN     EFI_MTFTP4_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     BOOLEAN                 Overwrite,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINT8                   *BufferPtr,\r
+  IN OUT UINT64                  *BufferSize\r
   )\r
 {\r
-  EFI_MTFTP4_PROTOCOL *Mtftp4;\r
-  EFI_MTFTP4_TOKEN    Token;\r
-  EFI_MTFTP4_OPTION   ReqOpt[1];\r
-  UINT32              OptCnt;\r
-  UINT8               OptBuf[128];\r
-  EFI_STATUS          Status;\r
+  EFI_MTFTP4_PROTOCOL  *Mtftp4;\r
+  EFI_MTFTP4_TOKEN     Token;\r
+  EFI_MTFTP4_OPTION    ReqOpt[1];\r
+  UINT32               OptCnt;\r
+  UINT8                OptBuf[128];\r
+  EFI_STATUS           Status;\r
 \r
   Status                    = EFI_DEVICE_ERROR;\r
   Mtftp4                    = Private->Mtftp4;\r
   OptCnt                    = 0;\r
   Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
 \r
-  Status  = Mtftp4->Configure (Mtftp4, Config);\r
+  Status = Mtftp4->Configure (Mtftp4, Config);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[0].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
     ReqOpt[0].ValueStr  = OptBuf;\r
     PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
     OptCnt++;\r
@@ -831,7 +881,6 @@ PxeBcMtftp4WriteFile (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is to get data (file) from a directory using Tftp.\r
 \r
@@ -839,32 +888,35 @@ PxeBcMtftp4WriteFile (
   @param[in]       Config         Pointer to EFI_MTFTP4_CONFIG_DATA.\r
   @param[in]       Filename       Pointer to boot file name.\r
   @param[in]       BlockSize      Pointer to required block size.\r
+  @param[in]       WindowSize     Pointer to required window size.\r
   @param[in]       BufferPtr      Pointer to buffer.\r
   @param[in, out]  BufferSize     Pointer to buffer size.\r
   @param[in]       DontUseBuffer  Indicates whether to use a receive buffer.\r
 \r
-  @retval EFI_SUCCES         Successfully obtained the data from the file included in the directory.\r
+  @retval EFI_SUCCESS        Successfully obtained the data from the file included in the directory.\r
   @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.\r
   @retval Others             Operation failed.\r
 \r
 **/\r
 EFI_STATUS\r
 PxeBcMtftp4ReadDirectory (\r
-  IN     PXEBC_PRIVATE_DATA            *Private,\r
-  IN     EFI_MTFTP4_CONFIG_DATA        *Config,\r
-  IN     UINT8                         *Filename,\r
-  IN     UINTN                         *BlockSize,\r
-  IN     UINT8                         *BufferPtr,\r
-  IN OUT UINT64                        *BufferSize,\r
-  IN     BOOLEAN                       DontUseBuffer\r
+  IN     PXEBC_PRIVATE_DATA      *Private,\r
+  IN     EFI_MTFTP4_CONFIG_DATA  *Config,\r
+  IN     UINT8                   *Filename,\r
+  IN     UINTN                   *BlockSize,\r
+  IN     UINTN                   *WindowSize,\r
+  IN     UINT8                   *BufferPtr,\r
+  IN OUT UINT64                  *BufferSize,\r
+  IN     BOOLEAN                 DontUseBuffer\r
   )\r
 {\r
-  EFI_MTFTP4_PROTOCOL *Mtftp4;\r
-  EFI_MTFTP4_TOKEN    Token;\r
-  EFI_MTFTP4_OPTION   ReqOpt[1];\r
-  UINT32              OptCnt;\r
-  UINT8               OptBuf[128];\r
-  EFI_STATUS          Status;\r
+  EFI_MTFTP4_PROTOCOL  *Mtftp4;\r
+  EFI_MTFTP4_TOKEN     Token;\r
+  EFI_MTFTP4_OPTION    ReqOpt[2];\r
+  UINT32               OptCnt;\r
+  UINT8                BlksizeBuf[10];\r
+  UINT8                WindowsizeBuf[10];\r
+  EFI_STATUS           Status;\r
 \r
   Status                    = EFI_DEVICE_ERROR;\r
   Mtftp4                    = Private->Mtftp4;\r
@@ -877,26 +929,33 @@ PxeBcMtftp4ReadDirectory (
   }\r
 \r
   if (BlockSize != NULL) {\r
-    ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
-    ReqOpt[0].ValueStr  = OptBuf;\r
-    PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr, PXE_MTFTP_OPTBUF_MAXNUM_INDEX);\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = BlksizeBuf;\r
+    PxeBcUintnToAscDec (*BlockSize, ReqOpt[OptCnt].ValueStr, sizeof (BlksizeBuf));\r
+    OptCnt++;\r
+  }\r
+\r
+  if (WindowSize != NULL) {\r
+    ReqOpt[OptCnt].OptionStr = (UINT8 *)mMtftpOptions[PXE_MTFTP_OPTION_WINDOWSIZE_INDEX];\r
+    ReqOpt[OptCnt].ValueStr  = WindowsizeBuf;\r
+    PxeBcUintnToAscDec (*WindowSize, ReqOpt[OptCnt].ValueStr, sizeof (WindowsizeBuf));\r
     OptCnt++;\r
   }\r
 \r
-  Token.Event         = NULL;\r
-  Token.OverrideData  = NULL;\r
-  Token.Filename      = Filename;\r
-  Token.ModeStr       = NULL;\r
-  Token.OptionCount   = OptCnt;\r
-  Token.OptionList    = ReqOpt;\r
-  Token.Context       = Private;\r
+  Token.Event        = NULL;\r
+  Token.OverrideData = NULL;\r
+  Token.Filename     = Filename;\r
+  Token.ModeStr      = NULL;\r
+  Token.OptionCount  = OptCnt;\r
+  Token.OptionList   = ReqOpt;\r
+  Token.Context      = Private;\r
 \r
   if (DontUseBuffer) {\r
-    Token.BufferSize  = 0;\r
-    Token.Buffer      = NULL;\r
+    Token.BufferSize = 0;\r
+    Token.Buffer     = NULL;\r
   } else {\r
-    Token.BufferSize  = *BufferSize;\r
-    Token.Buffer      = BufferPtr;\r
+    Token.BufferSize = *BufferSize;\r
+    Token.Buffer     = BufferPtr;\r
   }\r
 \r
   Token.CheckPacket     = PxeBcMtftp4CheckPacket;\r
@@ -914,7 +973,6 @@ PxeBcMtftp4ReadDirectory (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is wrapper to get the file size using TFTP.\r
 \r
@@ -922,6 +980,7 @@ PxeBcMtftp4ReadDirectory (
   @param[in]      Config         Pointer to configure data.\r
   @param[in]      Filename       Pointer to boot file name.\r
   @param[in]      BlockSize      Pointer to required block size.\r
+  @param[in]      WindowSize     Pointer to required window size.\r
   @param[in, out] BufferSize     Pointer to buffer size.\r
 \r
   @retval EFI_SUCCESS        Successfully obtained the size of file.\r
@@ -932,33 +991,35 @@ PxeBcMtftp4ReadDirectory (
 **/\r
 EFI_STATUS\r
 PxeBcTftpGetFileSize (\r
-  IN     PXEBC_PRIVATE_DATA         *Private,\r
-  IN     VOID                       *Config,\r
-  IN     UINT8                      *Filename,\r
-  IN     UINTN                      *BlockSize,\r
-  IN OUT UINT64                     *BufferSize\r
+  IN     PXEBC_PRIVATE_DATA  *Private,\r
+  IN     VOID                *Config,\r
+  IN     UINT8               *Filename,\r
+  IN     UINTN               *BlockSize,\r
+  IN     UINTN               *WindowSize,\r
+  IN OUT UINT64              *BufferSize\r
   )\r
 {\r
   if (Private->PxeBc.Mode->UsingIpv6) {\r
     return PxeBcMtftp6GetFileSize (\r
              Private,\r
-             (EFI_MTFTP6_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP6_CONFIG_DATA *)Config,\r
              Filename,\r
              BlockSize,\r
+             WindowSize,\r
              BufferSize\r
              );\r
   } else {\r
     return PxeBcMtftp4GetFileSize (\r
              Private,\r
-             (EFI_MTFTP4_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP4_CONFIG_DATA *)Config,\r
              Filename,\r
              BlockSize,\r
+             WindowSize,\r
              BufferSize\r
              );\r
   }\r
 }\r
 \r
-\r
 /**\r
   This function is a wrapper to get file using TFTP.\r
 \r
@@ -966,32 +1027,35 @@ PxeBcTftpGetFileSize (
   @param[in]      Config         Pointer to config data.\r
   @param[in]      Filename       Pointer to boot file name.\r
   @param[in]      BlockSize      Pointer to required block size.\r
+  @param[in]      WindowSize     Pointer to required window size.\r
   @param[in]      BufferPtr      Pointer to buffer.\r
   @param[in, out] BufferSize     Pointer to buffer size.\r
   @param[in]      DontUseBuffer  Indicates whether to use a receive buffer.\r
 \r
-  @retval EFI_SUCCESS        Sucessfully read the data from the special file.\r
+  @retval EFI_SUCCESS        Successfully read the data from the special file.\r
   @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.\r
   @retval Others             Read data from file failed.\r
 \r
 **/\r
 EFI_STATUS\r
 PxeBcTftpReadFile (\r
-  IN     PXEBC_PRIVATE_DATA         *Private,\r
-  IN     VOID                       *Config,\r
-  IN     UINT8                      *Filename,\r
-  IN     UINTN                      *BlockSize,\r
-  IN     UINT8                      *BufferPtr,\r
-  IN OUT UINT64                     *BufferSize,\r
-  IN     BOOLEAN                    DontUseBuffer\r
+  IN     PXEBC_PRIVATE_DATA  *Private,\r
+  IN     VOID                *Config,\r
+  IN     UINT8               *Filename,\r
+  IN     UINTN               *BlockSize,\r
+  IN     UINTN               *WindowSize,\r
+  IN     UINT8               *BufferPtr,\r
+  IN OUT UINT64              *BufferSize,\r
+  IN     BOOLEAN             DontUseBuffer\r
   )\r
 {\r
   if (Private->PxeBc.Mode->UsingIpv6) {\r
     return PxeBcMtftp6ReadFile (\r
              Private,\r
-             (EFI_MTFTP6_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP6_CONFIG_DATA *)Config,\r
              Filename,\r
              BlockSize,\r
+             WindowSize,\r
              BufferPtr,\r
              BufferSize,\r
              DontUseBuffer\r
@@ -999,9 +1063,10 @@ PxeBcTftpReadFile (
   } else {\r
     return PxeBcMtftp4ReadFile (\r
              Private,\r
-             (EFI_MTFTP4_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP4_CONFIG_DATA *)Config,\r
              Filename,\r
              BlockSize,\r
+             WindowSize,\r
              BufferPtr,\r
              BufferSize,\r
              DontUseBuffer\r
@@ -1009,7 +1074,6 @@ PxeBcTftpReadFile (
   }\r
 }\r
 \r
-\r
 /**\r
   This function is a wrapper to write file using TFTP.\r
 \r
@@ -1028,19 +1092,19 @@ PxeBcTftpReadFile (
 **/\r
 EFI_STATUS\r
 PxeBcTftpWriteFile (\r
-  IN     PXEBC_PRIVATE_DATA         *Private,\r
-  IN     VOID                       *Config,\r
-  IN     UINT8                      *Filename,\r
-  IN     BOOLEAN                    Overwrite,\r
-  IN     UINTN                      *BlockSize,\r
-  IN     UINT8                      *BufferPtr,\r
-  IN OUT UINT64                     *BufferSize\r
+  IN     PXEBC_PRIVATE_DATA  *Private,\r
+  IN     VOID                *Config,\r
+  IN     UINT8               *Filename,\r
+  IN     BOOLEAN             Overwrite,\r
+  IN     UINTN               *BlockSize,\r
+  IN     UINT8               *BufferPtr,\r
+  IN OUT UINT64              *BufferSize\r
   )\r
 {\r
   if (Private->PxeBc.Mode->UsingIpv6) {\r
     return PxeBcMtftp6WriteFile (\r
              Private,\r
-             (EFI_MTFTP6_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP6_CONFIG_DATA *)Config,\r
              Filename,\r
              Overwrite,\r
              BlockSize,\r
@@ -1050,7 +1114,7 @@ PxeBcTftpWriteFile (
   } else {\r
     return PxeBcMtftp4WriteFile (\r
              Private,\r
-             (EFI_MTFTP4_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP4_CONFIG_DATA *)Config,\r
              Filename,\r
              Overwrite,\r
              BlockSize,\r
@@ -1060,7 +1124,6 @@ PxeBcTftpWriteFile (
   }\r
 }\r
 \r
-\r
 /**\r
   This function is a wrapper to get the data (file) from a directory using TFTP.\r
 \r
@@ -1068,32 +1131,35 @@ PxeBcTftpWriteFile (
   @param[in]       Config         Pointer to config data.\r
   @param[in]       Filename       Pointer to boot file name.\r
   @param[in]       BlockSize      Pointer to required block size.\r
+  @param[in]       WindowSize     Pointer to required window size.\r
   @param[in]       BufferPtr      Pointer to buffer.\r
   @param[in, out]  BufferSize     Pointer to buffer size.\r
   @param[in]       DontUseBuffer  Indicatse whether to use a receive buffer.\r
 \r
-  @retval EFI_SUCCES         Successfully obtained the data from the file included in the directory.\r
+  @retval EFI_SUCCESS        Successfully obtained the data from the file included in the directory.\r
   @retval EFI_DEVICE_ERROR   The network device encountered an error during this operation.\r
   @retval Others             Operation failed.\r
 \r
 **/\r
 EFI_STATUS\r
 PxeBcTftpReadDirectory (\r
-  IN     PXEBC_PRIVATE_DATA            *Private,\r
-  IN     VOID                          *Config,\r
-  IN     UINT8                         *Filename,\r
-  IN     UINTN                         *BlockSize,\r
-  IN     UINT8                         *BufferPtr,\r
-  IN OUT UINT64                        *BufferSize,\r
-  IN     BOOLEAN                       DontUseBuffer\r
+  IN     PXEBC_PRIVATE_DATA  *Private,\r
+  IN     VOID                *Config,\r
+  IN     UINT8               *Filename,\r
+  IN     UINTN               *BlockSize,\r
+  IN     UINTN               *WindowSize,\r
+  IN     UINT8               *BufferPtr,\r
+  IN OUT UINT64              *BufferSize,\r
+  IN     BOOLEAN             DontUseBuffer\r
   )\r
 {\r
   if (Private->PxeBc.Mode->UsingIpv6) {\r
     return PxeBcMtftp6ReadDirectory (\r
              Private,\r
-             (EFI_MTFTP6_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP6_CONFIG_DATA *)Config,\r
              Filename,\r
              BlockSize,\r
+             WindowSize,\r
              BufferPtr,\r
              BufferSize,\r
              DontUseBuffer\r
@@ -1101,13 +1167,13 @@ PxeBcTftpReadDirectory (
   } else {\r
     return PxeBcMtftp4ReadDirectory (\r
              Private,\r
-             (EFI_MTFTP4_CONFIG_DATA *) Config,\r
+             (EFI_MTFTP4_CONFIG_DATA *)Config,\r
              Filename,\r
              BlockSize,\r
+             WindowSize,\r
              BufferPtr,\r
              BufferSize,\r
              DontUseBuffer\r
              );\r
   }\r
 }\r
-\r