]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / DynamicCommand / TftpDynamicCommand / Tftp.c
index ed081b5bad7cf5a4b5f16ee506d259a20ad6e178..7e5c73b3daaa82b11a2e1904f841f5a85f58b32e 100644 (file)
@@ -5,27 +5,21 @@
   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
-  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
 #include "Tftp.h"\r
 \r
-#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32\r
-EFI_HANDLE   mTftpHiiHandle;\r
+#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH  32\r
+EFI_HII_HANDLE  mTftpHiiHandle;\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
+   progress in the downloading of a TFTP file.\r
 */\r
 \r
 // Frame for the progression slider\r
-STATIC CONST CHAR16 mTftpProgressFrame[] = L"[                                        ]";\r
+STATIC CONST CHAR16  mTftpProgressFrame[] = L"[                                        ]";\r
 \r
 // Number of steps in the progression slider\r
 #define TFTP_PROGRESS_SLIDER_STEPS  ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3)\r
@@ -39,7 +33,13 @@ STATIC CONST CHAR16 mTftpProgressFrame[] = L"[
 \r
 // String to delete the TFTP progress message to be able to update it :\r
 // (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
+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
@@ -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\r
 \r
   @return     TRUE      The value was returned.\r
-  @return     FALSE     A parsing error occured.\r
+  @return     FALSE     A parsing error occurred.\r
 **/\r
 STATIC\r
 BOOLEAN\r
@@ -166,9 +166,6 @@ GetFileSize (
   @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
@@ -184,8 +181,7 @@ DownloadFile (
   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
@@ -210,49 +206,57 @@ CheckPacket (
   IN EFI_MTFTP4_PACKET    *Packet\r
   );\r
 \r
-EFI_MTFTP4_CONFIG_DATA DefaultMtftp4ConfigData = {\r
+EFI_MTFTP4_CONFIG_DATA  DefaultMtftp4ConfigData = {\r
   TRUE,                             // Use default setting\r
-  { { 0, 0, 0, 0 } },               // StationIp         - Not relevant as UseDefaultSetting=TRUE\r
-  { { 0, 0, 0, 0 } },               // SubnetMask        - Not relevant as UseDefaultSetting=TRUE\r
+  {\r
+    { 0, 0, 0, 0 }\r
+  },                                // StationIp         - Not relevant as UseDefaultSetting=TRUE\r
+  {\r
+    { 0, 0, 0, 0 }\r
+  },                                // SubnetMask        - Not relevant as UseDefaultSetting=TRUE\r
   0,                                // LocalPort         - Automatically assigned port number.\r
-  { { 0, 0, 0, 0 } },               // GatewayIp         - Not relevant as UseDefaultSetting=TRUE\r
-  { { 0, 0, 0, 0 } },               // ServerIp          - Not known yet\r
+  {\r
+    { 0, 0, 0, 0 }\r
+  },                                // GatewayIp         - Not relevant as UseDefaultSetting=TRUE\r
+  {\r
+    { 0, 0, 0, 0 }\r
+  },                                // ServerIp          - Not known yet\r
   69,                               // InitialServerPort - Standard TFTP server port\r
   6,                                // TryCount          - The number of times to transmit request packets and wait for a response.\r
   4                                 // TimeoutValue      - Retransmission timeout in seconds.\r
 };\r
 \r
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
-  {L"-i", TypeValue},\r
-  {L"-l", TypeValue},\r
-  {L"-r", TypeValue},\r
-  {L"-c", TypeValue},\r
-  {L"-t", TypeValue},\r
-  {L"-s", TypeValue},\r
-  {L"-w", TypeValue},\r
-  {NULL , TypeMax}\r
-  };\r
+STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {\r
+  { L"-i", TypeValue },\r
+  { L"-l", TypeValue },\r
+  { L"-r", TypeValue },\r
+  { L"-c", TypeValue },\r
+  { L"-t", TypeValue },\r
+  { L"-s", TypeValue },\r
+  { L"-w", 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
+#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
+#define MTFTP_MIN_BLKSIZE  8\r
+#define MTFTP_MAX_BLKSIZE  65464\r
 ///\r
 /// The default windowsize (1) of tftp.\r
 ///\r
-#define MTFTP_DEFAULT_WINDOWSIZE   1\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
+#define MTFTP_MIN_WINDOWSIZE  1\r
+#define MTFTP_MAX_WINDOWSIZE  64\r
 \r
 /**\r
   Function for 'tftp' command.\r
@@ -287,7 +291,6 @@ RunTftp (
   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
@@ -297,9 +300,6 @@ RunTftp (
   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
@@ -309,7 +309,6 @@ RunTftp (
   AsciiRemoteFilePath = NULL;\r
   Handles             = NULL;\r
   FileSize            = 0;\r
-  DataSize            = 0;\r
   BlockSize           = MTFTP_DEFAULT_BLKSIZE;\r
   WindowSize          = MTFTP_DEFAULT_WINDOWSIZE;\r
 \r
@@ -328,15 +327,22 @@ RunTftp (
   Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);\r
   if (EFI_ERROR (Status)) {\r
     if ((Status == EFI_VOLUME_CORRUPTED) &&\r
-        (ProblemParam != NULL) ) {\r
+        (ProblemParam != NULL))\r
+    {\r
       ShellPrintHiiEx (\r
-        -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), mTftpHiiHandle,\r
-        L"tftp", ProblemParam\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_PROBLEM),\r
+        mTftpHiiHandle,\r
+        L"tftp",\r
+        ProblemParam\r
         );\r
       FreePool (ProblemParam);\r
     } else {\r
       ASSERT (FALSE);\r
     }\r
+\r
     goto Error;\r
   }\r
 \r
@@ -346,15 +352,24 @@ RunTftp (
   ParamCount = ShellCommandLineGetCount (CheckPackage);\r
   if (ParamCount > 4) {\r
     ShellPrintHiiEx (\r
-      -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY),\r
-      mTftpHiiHandle, L"tftp"\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_TOO_MANY),\r
+      mTftpHiiHandle,\r
+      L"tftp"\r
       );\r
     goto Error;\r
   }\r
+\r
   if (ParamCount < 3) {\r
     ShellPrintHiiEx (\r
-      -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW),\r
-      mTftpHiiHandle, L"tftp"\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_TOO_FEW),\r
+      mTftpHiiHandle,\r
+      L"tftp"\r
       );\r
     goto Error;\r
   }\r
@@ -365,36 +380,44 @@ RunTftp (
   // Check the host IPv4 address\r
   //\r
   ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);\r
-  Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);\r
+  Status   = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);\r
   if (EFI_ERROR (Status)) {\r
     ShellPrintHiiEx (\r
-      -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
-      mTftpHiiHandle, L"tftp", ValueStr\r
-    );\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_PARAM_INV),\r
+      mTftpHiiHandle,\r
+      L"tftp",\r
+      ValueStr\r
+      );\r
     goto Error;\r
   }\r
 \r
   RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);\r
-  ASSERT(RemoteFilePath != NULL);\r
-  FilePathSize = StrLen (RemoteFilePath) + 1;\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
+\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
       if ((*Walker == L'\\') ||\r
-          (*Walker == L'/' )    ) {\r
+          (*Walker == L'/'))\r
+      {\r
         break;\r
       }\r
     }\r
-    LocalFilePath = Walker + 1;\r
+\r
+    mLocalFilePath = Walker + 1;\r
   }\r
 \r
   //\r
@@ -432,11 +455,17 @@ RunTftp (
     if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) {\r
       goto Error;\r
     }\r
+\r
     if (Mtftp4ConfigData.TimeoutValue == 0) {\r
       ShellPrintHiiEx (\r
-        -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
-        mTftpHiiHandle, L"tftp", ValueStr\r
-      );\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_PARAM_INV),\r
+        mTftpHiiHandle,\r
+        L"tftp",\r
+        ValueStr\r
+        );\r
       goto Error;\r
     }\r
   }\r
@@ -446,11 +475,17 @@ RunTftp (
     if (!StringToUint16 (ValueStr, &BlockSize)) {\r
       goto Error;\r
     }\r
-    if (BlockSize < MTFTP_MIN_BLKSIZE || BlockSize > MTFTP_MAX_BLKSIZE) {\r
+\r
+    if ((BlockSize < MTFTP_MIN_BLKSIZE) || (BlockSize > MTFTP_MAX_BLKSIZE)) {\r
       ShellPrintHiiEx (\r
-        -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
-        mTftpHiiHandle, L"tftp", ValueStr\r
-      );\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_PARAM_INV),\r
+        mTftpHiiHandle,\r
+        L"tftp",\r
+        ValueStr\r
+        );\r
       goto Error;\r
     }\r
   }\r
@@ -460,11 +495,17 @@ RunTftp (
     if (!StringToUint16 (ValueStr, &WindowSize)) {\r
       goto Error;\r
     }\r
-    if (WindowSize < MTFTP_MIN_WINDOWSIZE || WindowSize > MTFTP_MAX_WINDOWSIZE) {\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
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_PARAM_INV),\r
+        mTftpHiiHandle,\r
+        L"tftp",\r
+        ValueStr\r
+        );\r
       goto Error;\r
     }\r
   }\r
@@ -473,33 +514,41 @@ RunTftp (
   // Locate all MTFTP4 Service Binding protocols\r
   //\r
   ShellStatus = SHELL_NOT_FOUND;\r
-  Status = gBS->LocateHandleBuffer (\r
-                 ByProtocol,\r
-                 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
-                 NULL,\r
-                 &HandleCount,\r
-                 &Handles\r
-                 );\r
+  Status      = gBS->LocateHandleBuffer (\r
+                       ByProtocol,\r
+                       &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+                       NULL,\r
+                       &HandleCount,\r
+                       &Handles\r
+                       );\r
   if (EFI_ERROR (Status) || (HandleCount == 0)) {\r
     ShellPrintHiiEx (\r
-      -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NO_NIC),\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_TFTP_ERR_NO_NIC),\r
       mTftpHiiHandle\r
-    );\r
+      );\r
     goto Error;\r
   }\r
 \r
   for (NicNumber = 0;\r
        (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS);\r
-       NicNumber++) {\r
+       NicNumber++)\r
+  {\r
     ControllerHandle = Handles[NicNumber];\r
-    Data = NULL;\r
 \r
     Status = GetNicName (ControllerHandle, NicNumber, NicName);\r
     if (EFI_ERROR (Status)) {\r
       ShellPrintHiiEx (\r
-        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NAME),\r
-        mTftpHiiHandle, NicNumber, Status\r
-      );\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_TFTP_ERR_NIC_NAME),\r
+        mTftpHiiHandle,\r
+        NicNumber,\r
+        Status\r
+        );\r
       continue;\r
     }\r
 \r
@@ -507,6 +556,7 @@ RunTftp (
       if (StrCmp (NicName, UserNicName) != 0) {\r
         continue;\r
       }\r
+\r
       NicFound = TRUE;\r
     }\r
 \r
@@ -515,81 +565,68 @@ RunTftp (
                &gEfiMtftp4ServiceBindingProtocolGuid,\r
                &gEfiMtftp4ProtocolGuid,\r
                &Mtftp4ChildHandle,\r
-               (VOID**)&Mtftp4\r
+               (VOID **)&Mtftp4\r
                );\r
     if (EFI_ERROR (Status)) {\r
       ShellPrintHiiEx (\r
-        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),\r
-        mTftpHiiHandle, NicName, Status\r
-      );\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),\r
+        mTftpHiiHandle,\r
+        NicName,\r
+        Status\r
+        );\r
       continue;\r
     }\r
 \r
     Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData);\r
     if (EFI_ERROR (Status)) {\r
       ShellPrintHiiEx (\r
-        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_CONFIGURE),\r
-        mTftpHiiHandle, NicName, Status\r
-      );\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_TFTP_ERR_CONFIGURE),\r
+        mTftpHiiHandle,\r
+        NicName,\r
+        Status\r
+        );\r
       goto NextHandle;\r
     }\r
 \r
     Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize);\r
     if (EFI_ERROR (Status)) {\r
       ShellPrintHiiEx (\r
-        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE),\r
-        mTftpHiiHandle, RemoteFilePath, NicName, Status\r
-      );\r
-      goto NextHandle;\r
-    }\r
-\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
-        mTftpHiiHandle, RemoteFilePath, NicName, Status\r
-      );\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE),\r
+        mTftpHiiHandle,\r
+        RemoteFilePath,\r
+        NicName,\r
+        Status\r
+        );\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
+    Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize);\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
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),\r
+        mTftpHiiHandle,\r
+        RemoteFilePath,\r
+        NicName,\r
+        Status\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
+    ShellStatus = SHELL_SUCCESS;\r
 \r
-    NextHandle:\r
-\r
-    if (Data != NULL) {\r
-      gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (DataSize));\r
-    }\r
+NextHandle:\r
 \r
     CloseProtocolAndDestroyServiceChild (\r
       ControllerHandle,\r
@@ -601,21 +638,30 @@ RunTftp (
 \r
   if ((UserNicName != NULL) && (!NicFound)) {\r
     ShellPrintHiiEx (\r
-      -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),\r
-      mTftpHiiHandle, UserNicName\r
-    );\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),\r
+      mTftpHiiHandle,\r
+      UserNicName\r
+      );\r
   }\r
 \r
-  Error:\r
+Error:\r
 \r
   ShellCommandLineFreeVarList (CheckPackage);\r
   if (AsciiRemoteFilePath != NULL) {\r
     FreePool (AsciiRemoteFilePath);\r
   }\r
+\r
   if (Handles != NULL) {\r
     FreePool (Handles);\r
   }\r
 \r
+  if ((ShellStatus != SHELL_SUCCESS) && (EFI_ERROR (Status))) {\r
+    ShellStatus = Status & ~MAX_BIT;\r
+  }\r
+\r
   return ShellStatus;\r
 }\r
 \r
@@ -626,7 +672,7 @@ RunTftp (
   @param[out] Value     UINT16 value\r
 \r
   @return     TRUE      The value was returned.\r
-  @return     FALSE     A parsing error occured.\r
+  @return     FALSE     A parsing error occurred.\r
 **/\r
 STATIC\r
 BOOLEAN\r
@@ -640,9 +686,14 @@ StringToUint16 (
   Val = ShellStrToUintn (ValueStr);\r
   if (Val > MAX_UINT16) {\r
     ShellPrintHiiEx (\r
-      -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
-      mTftpHiiHandle, L"tftp", ValueStr\r
-    );\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_PARAM_INV),\r
+      mTftpHiiHandle,\r
+      L"tftp",\r
+      ValueStr\r
+      );\r
     return FALSE;\r
   }\r
 \r
@@ -686,7 +737,7 @@ GetNicName (
              &gEfiManagedNetworkServiceBindingProtocolGuid,\r
              &gEfiManagedNetworkProtocolGuid,\r
              &MnpHandle,\r
-             (VOID**)&Mnp\r
+             (VOID **)&Mnp\r
              );\r
   if (EFI_ERROR (Status)) {\r
     goto Error;\r
@@ -702,7 +753,7 @@ GetNicName (
     IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,\r
     SnpMode.IfType == NET_IFTYPE_ETHERNET ?\r
     L"eth%d" :\r
-    L"unk%d" ,\r
+    L"unk%d",\r
     NicNumber\r
     );\r
 \r
@@ -754,12 +805,12 @@ CreateServiceChildAndOpenProtocol (
   EFI_STATUS  Status;\r
 \r
   *ChildHandle = NULL;\r
-  Status = NetLibCreateServiceChild (\r
-             ControllerHandle,\r
-             gImageHandle,\r
-             ServiceBindingProtocolGuid,\r
-             ChildHandle\r
-             );\r
+  Status       = NetLibCreateServiceChild (\r
+                   ControllerHandle,\r
+                   gImageHandle,\r
+                   ServiceBindingProtocolGuid,\r
+                   ChildHandle\r
+                   );\r
   if (!EFI_ERROR (Status)) {\r
     Status = gBS->OpenProtocol (\r
                     *ChildHandle,\r
@@ -851,21 +902,21 @@ GetFileSize (
   UINT32             OptCnt;\r
   UINT8              OptBuf[128];\r
 \r
-  ReqOpt[0].OptionStr = (UINT8*)"tsize";\r
-  OptBuf[0] = '0';\r
-  OptBuf[1] = 0;\r
-  ReqOpt[0].ValueStr = OptBuf;\r
+  ReqOpt[0].OptionStr = (UINT8 *)"tsize";\r
+  OptBuf[0]           = '0';\r
+  OptBuf[1]           = 0;\r
+  ReqOpt[0].ValueStr  = OptBuf;\r
 \r
   Status = Mtftp4->GetInfo (\r
-             Mtftp4,\r
-             NULL,\r
-             (UINT8*)FilePath,\r
-             NULL,\r
-             1,\r
-             ReqOpt,\r
-             &PktLen,\r
-             &Packet\r
-             );\r
+                     Mtftp4,\r
+                     NULL,\r
+                     (UINT8 *)FilePath,\r
+                     NULL,\r
+                     1,\r
+                     ReqOpt,\r
+                     &PktLen,\r
+                     &Packet\r
+                     );\r
 \r
   if (EFI_ERROR (Status)) {\r
     goto Error;\r
@@ -875,7 +926,7 @@ GetFileSize (
                      Mtftp4,\r
                      PktLen,\r
                      Packet,\r
-                     (UINT32 *) &OptCnt,\r
+                     (UINT32 *)&OptCnt,\r
                      &TableOfOptions\r
                      );\r
   if (EFI_ERROR (Status)) {\r
@@ -888,16 +939,18 @@ GetFileSize (
       *FileSize = AsciiStrDecimalToUintn ((CHAR8 *)Option->ValueStr);\r
       break;\r
     }\r
+\r
     OptCnt--;\r
     Option++;\r
   }\r
+\r
   FreePool (TableOfOptions);\r
 \r
   if (OptCnt == 0) {\r
     Status = EFI_UNSUPPORTED;\r
   }\r
 \r
-Error :\r
+Error:\r
 \r
   return Status;\r
 }\r
@@ -912,9 +965,6 @@ Error :
   @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
@@ -930,50 +980,30 @@ DownloadFile (
   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
-  UINT8                 WindowsizeBuf[10];\r
+  EFI_STATUS        Status;\r
+  DOWNLOAD_CONTEXT  *TftpContext;\r
+  EFI_MTFTP4_TOKEN  Mtftp4Token;\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
-  // 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
     goto Error;\r
   }\r
-  TftpContext->FileSize = FileSize;\r
+\r
+  TftpContext->FileSize              = FileSize;\r
   TftpContext->DownloadedNbOfBytes   = 0;\r
   TftpContext->LastReportedNbOfBytes = 0;\r
 \r
-  Mtftp4Token.Filename    = (UINT8*)AsciiFilePath;\r
-  Mtftp4Token.BufferSize  = FileSize;\r
-  Mtftp4Token.Buffer      = Buffer;\r
+  Mtftp4Token.Filename    = (UINT8 *)AsciiFilePath;\r
   Mtftp4Token.CheckPacket = CheckPacket;\r
-  Mtftp4Token.Context     = (VOID*)TftpContext;\r
+  Mtftp4Token.Context     = (VOID *)TftpContext;\r
   Mtftp4Token.OptionCount = 0;\r
   Mtftp4Token.OptionList  = AllocatePool (sizeof (EFI_MTFTP4_OPTION) * 2);\r
   if (Mtftp4Token.OptionList == NULL) {\r
@@ -982,32 +1012,71 @@ DownloadFile (
   }\r
 \r
   if (BlockSize != MTFTP_DEFAULT_BLKSIZE) {\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
+    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
   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
+    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
-    -1, -1, NULL, STRING_TOKEN (STR_TFTP_DOWNLOADING),\r
-    mTftpHiiHandle, FilePath\r
+    -1,\r
+    -1,\r
+    NULL,\r
+    STRING_TOKEN (STR_TFTP_DOWNLOADING),\r
+    mTftpHiiHandle,\r
+    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,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),\r
+      mTftpHiiHandle,\r
+      L"tftp",\r
+      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
+    -1,\r
+    -1,\r
+    NULL,\r
+    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
@@ -1016,14 +1085,7 @@ Error :
     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
@@ -1054,29 +1116,57 @@ CheckPacket (
   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
     return EFI_SUCCESS;\r
   }\r
 \r
-  Context = (DOWNLOAD_CONTEXT*)Token->Context;\r
-  if (Context->DownloadedNbOfBytes == 0) {\r
-    ShellPrintEx (-1, -1, L"%s       0 Kb", mTftpProgressFrame);\r
-  }\r
+  Context = (DOWNLOAD_CONTEXT *)Token->Context;\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
-  NbOfKb = Context->DownloadedNbOfBytes / 1024;\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,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_CRLF),\r
+        mTftpHiiHandle\r
+        );\r
+    }\r
+\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_TFTP_ERR_WRITE),\r
+      mTftpHiiHandle,\r
+      mLocalFilePath,\r
+      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
-  LastStep  = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;\r
-  Step      = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / 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
@@ -1085,12 +1175,14 @@ CheckPacket (
   ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete);\r
 \r
   Status = StrCpyS (Progress, TFTP_PROGRESS_MESSAGE_SIZE, mTftpProgressFrame);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
   for (Index = 1; Index < Step; Index++) {\r
     Progress[Index] = L'=';\r
   }\r
+\r
   Progress[Step] = L'>';\r
 \r
   UnicodeSPrint (\r
@@ -1107,20 +1199,20 @@ CheckPacket (
 }\r
 \r
 /**\r
-  Retrive HII package list from ImageHandle and publish to HII database.\r
+  Retrieve HII package list from ImageHandle and publish to HII database.\r
 \r
   @param ImageHandle            The image handle of the process.\r
 \r
   @return HII handle.\r
 **/\r
-EFI_HANDLE\r
+EFI_HII_HANDLE\r
 InitializeHiiPackage (\r
-  EFI_HANDLE                  ImageHandle\r
+  EFI_HANDLE  ImageHandle\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
-  EFI_HANDLE                  HiiHandle;\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *PackageList;\r
+  EFI_HII_HANDLE               HiiHandle;\r
 \r
   //\r
   // Retrieve HII package list from ImageHandle\r
@@ -1151,5 +1243,6 @@ InitializeHiiPackage (
   if (EFI_ERROR (Status)) {\r
     return NULL;\r
   }\r
+\r
   return HiiHandle;\r
 }\r