]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ShellPkg: Add optional 'tftp' EFI Shell command
authorRonald Cron <Ronald.Cron@arm.com>
Wed, 15 Jul 2015 15:39:53 +0000 (15:39 +0000)
committeroliviermartin <oliviermartin@Edk2>
Wed, 15 Jul 2015 15:39:53 +0000 (15:39 +0000)
This 'tftp' command allows to download a file from a TFTP server.
A specific network interface can be chosen in case there are multiple
interfaces.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ronald Cron <Ronald.Cron@arm.com>
Reviewed-by: Olivier Martin <Olivier.Martin@arm.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18015 6f19259b-4bc3-4df7-8a09-765794883524

ShellPkg/Include/Guid/ShellLibHiiGuid.h
ShellPkg/Library/UefiShellTftpCommandLib/Tftp.c [new file with mode: 0644]
ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.c [new file with mode: 0644]
ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.h [new file with mode: 0644]
ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf [new file with mode: 0644]
ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.uni [new file with mode: 0644]
ShellPkg/ShellPkg.dec
ShellPkg/ShellPkg.dsc

index dc694f2915c3aeb9bb8cd3632bc2860662571abd..62c2e72ec99fc86cebf7f0a8076b4fbf17a87b41 100644 (file)
   { \\r
     0xf3d301bb, 0xf4a5, 0x45a8, { 0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae } \\r
   }\r
+#define SHELL_TFTP_HII_GUID \\r
+  { \\r
+    0x738a9314, 0x82c1, 0x4592, { 0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4 } \\r
+  }\r
+\r
+\r
 #define SHELL_BCFG_HII_GUID \\r
   { \\r
     0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6 } \\r
@@ -67,6 +73,7 @@ extern EFI_GUID gShellLevel1HiiGuid;
 extern EFI_GUID gShellLevel2HiiGuid;\r
 extern EFI_GUID gShellLevel3HiiGuid;\r
 extern EFI_GUID gShellNetwork1HiiGuid;\r
+extern EFI_GUID gShellTftpHiiGuid;\r
 extern EFI_GUID gShellBcfgHiiGuid;\r
 \r
 #endif\r
diff --git a/ShellPkg/Library/UefiShellTftpCommandLib/Tftp.c b/ShellPkg/Library/UefiShellTftpCommandLib/Tftp.c
new file mode 100644 (file)
index 0000000..b872afd
--- /dev/null
@@ -0,0 +1,880 @@
+/** @file\r
+  The implementation for the 'tftp' Shell command.\r
+\r
+  Copyright (c) 2015, ARM Ltd. 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
+**/\r
+\r
+#include "UefiShellTftpCommandLib.h"\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
+*/\r
+\r
+// Frame for the progression slider\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
+\r
+// Size in number of characters plus one (final zero) of the message to\r
+// indicate the progress of a TFTP download. The format is "[(progress slider:\r
+// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There\r
+// are thus the number of characters in mTftpProgressFrame[] plus 11 characters\r
+// (2 // spaces, "Kb" and seven characters for the number of KBytes).\r
+#define TFTP_PROGRESS_MESSAGE_SIZE  ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) + 12)\r
+\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
+\r
+STATIC BOOLEAN StringToUint16 (\r
+  IN   CONST CHAR16  *ValueStr,\r
+  OUT  UINT16        *Value\r
+  );\r
+\r
+STATIC EFI_STATUS GetNicName (\r
+  IN   EFI_HANDLE  ControllerHandle,\r
+  IN   UINTN       Index,\r
+  OUT  CHAR16      *NicName\r
+  );\r
+\r
+STATIC EFI_STATUS CreateServiceChildAndOpenProtocol (\r
+  IN   EFI_HANDLE  ControllerHandle,\r
+  IN   EFI_GUID    *ServiceBindingProtocolGuid,\r
+  IN   EFI_GUID    *ProtocolGuid,\r
+  OUT  EFI_HANDLE  *ChildHandle,\r
+  OUT  VOID        **Interface\r
+  );\r
+\r
+STATIC VOID CloseProtocolAndDestroyServiceChild (\r
+  IN  EFI_HANDLE  ControllerHandle,\r
+  IN  EFI_GUID    *ServiceBindingProtocolGuid,\r
+  IN  EFI_GUID    *ProtocolGuid,\r
+  IN  EFI_HANDLE  ChildHandle\r
+  );\r
+\r
+STATIC EFI_STATUS GetFileSize (\r
+  IN   EFI_MTFTP4_PROTOCOL  *Mtftp4,\r
+  IN   CONST CHAR8          *FilePath,\r
+  OUT  UINTN                *FileSize\r
+  );\r
+\r
+STATIC EFI_STATUS DownloadFile (\r
+  IN   EFI_MTFTP4_PROTOCOL  *Mtftp4,\r
+  IN   CONST CHAR16         *FilePath,\r
+  IN   CONST CHAR8          *AsciiFilePath,\r
+  IN   UINTN                FileSize,\r
+  OUT  VOID                 **Data\r
+  );\r
+\r
+STATIC EFI_STATUS CheckPacket (\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
+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
+  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
+  69,                               // InitialServerPort - Standard TFTP server port\r
+  6,                                // TryCount          - Max number of retransmissions.\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
+  {NULL , TypeMax}\r
+  };\r
+\r
+/**\r
+  Function for 'tftp' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+\r
+  @return  SHELL_SUCCESS            The 'tftp' command completed successfully.\r
+  @return  SHELL_ABORTED            The Shell Library initialization failed.\r
+  @return  SHELL_INVALID_PARAMETER  At least one of the command's arguments is\r
+                                    not valid.\r
+  @return  SHELL_OUT_OF_RESOURCES   A memory allocation failed.\r
+  @return  SHELL_NOT_FOUND          Network Interface Card not found or server\r
+                                    error or file error.\r
+\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunTftp (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  SHELL_STATUS            ShellStatus;\r
+  EFI_STATUS              Status;\r
+  LIST_ENTRY              *CheckPackage;\r
+  CHAR16                  *ProblemParam;\r
+  UINTN                   ParamCount;\r
+  CONST CHAR16            *UserNicName;\r
+  BOOLEAN                 NicFound;\r
+  CONST CHAR16            *ValueStr;\r
+  CONST CHAR16            *RemoteFilePath;\r
+  CHAR8                   *AsciiRemoteFilePath;\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
+  EFI_HANDLE              ControllerHandle;\r
+  EFI_HANDLE              Mtftp4ChildHandle;\r
+  EFI_MTFTP4_PROTOCOL     *Mtftp4;\r
+  UINTN                   FileSize;\r
+  VOID                    *Data;\r
+  SHELL_FILE_HANDLE       FileHandle;\r
+\r
+  ShellStatus         = SHELL_INVALID_PARAMETER;\r
+  ProblemParam        = NULL;\r
+  NicFound            = FALSE;\r
+  AsciiRemoteFilePath = NULL;\r
+  Handles             = NULL;\r
+\r
+  //\r
+  // Initialize the Shell library (we must be in non-auto-init...)\r
+  //\r
+  Status = ShellInitialize ();\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT_EFI_ERROR (Status);\r
+    return SHELL_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Parse the command line.\r
+  //\r
+  Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);\r
+  if (EFI_ERROR (Status)) {\r
+    if ((Status == EFI_VOLUME_CORRUPTED) &&\r
+        (ProblemParam != NULL) ) {\r
+      ShellPrintHiiEx (\r
+        -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellTftpHiiHandle,\r
+        L"tftp", ProblemParam\r
+        );\r
+      FreePool (ProblemParam);\r
+    } else {\r
+      ASSERT (FALSE);\r
+    }\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Check the number of parameters\r
+  //\r
+  ParamCount = ShellCommandLineGetCount (CheckPackage);\r
+  if (ParamCount > 4) {\r
+    ShellPrintHiiEx (\r
+      -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY),\r
+      gShellTftpHiiHandle, L"tftp"\r
+      );\r
+    goto Error;\r
+  }\r
+  if (ParamCount < 3) {\r
+    ShellPrintHiiEx (\r
+      -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW),\r
+      gShellTftpHiiHandle, L"tftp"\r
+      );\r
+    goto Error;\r
+  }\r
+\r
+  Mtftp4ConfigData = DefaultMtftp4ConfigData;\r
+\r
+  //\r
+  // Check the host IPv4 address\r
+  //\r
+  ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);\r
+  Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
+      gShellTftpHiiHandle, L"tftp", ValueStr\r
+    );\r
+    goto Error;\r
+  }\r
+\r
+  RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);\r
+  AsciiRemoteFilePath = AllocatePool (\r
+                          (StrLen (RemoteFilePath) + 1) * sizeof (CHAR8)\r
+                          );\r
+  if (AsciiRemoteFilePath == NULL) {\r
+    ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+    goto Error;\r
+  }\r
+  UnicodeStrToAsciiStr (RemoteFilePath, AsciiRemoteFilePath);\r
+\r
+  if (ParamCount == 4) {\r
+    LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);\r
+  } else {\r
+    Walker = RemoteFilePath + StrLen (RemoteFilePath);\r
+    while ((--Walker) >= RemoteFilePath) {\r
+      if ((*Walker == L'\\') ||\r
+          (*Walker == L'/' )    ) {\r
+        break;\r
+      }\r
+    }\r
+    LocalFilePath = Walker + 1;\r
+  }\r
+\r
+  //\r
+  // Get the name of the Network Interface Card to be used if any.\r
+  //\r
+  UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i");\r
+\r
+  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l");\r
+  if (ValueStr != NULL) {\r
+    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) {\r
+      goto Error;\r
+    }\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r");\r
+  if (ValueStr != NULL) {\r
+    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) {\r
+      goto Error;\r
+    }\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c");\r
+  if (ValueStr != NULL) {\r
+    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) {\r
+      goto Error;\r
+    }\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");\r
+  if (ValueStr != NULL) {\r
+    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) {\r
+      goto Error;\r
+    }\r
+    if (Mtftp4ConfigData.TimeoutValue == 0) {\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
+  ShellStatus = SHELL_NOT_FOUND;\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
+      gShellTftpHiiHandle\r
+    );\r
+    goto Error;\r
+  }\r
+\r
+  for (NicNumber = 0;\r
+       (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS);\r
+       NicNumber++) {\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
+        gShellTftpHiiHandle, NicNumber, Status\r
+      );\r
+      continue;\r
+    }\r
+\r
+    if (UserNicName != NULL) {\r
+      if (StrCmp (NicName, UserNicName) != 0) {\r
+        continue;\r
+      }\r
+      NicFound = TRUE;\r
+    }\r
+\r
+    Status = CreateServiceChildAndOpenProtocol (\r
+               ControllerHandle,\r
+               &gEfiMtftp4ServiceBindingProtocolGuid,\r
+               &gEfiMtftp4ProtocolGuid,\r
+               &Mtftp4ChildHandle,\r
+               (VOID**)&Mtftp4\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),\r
+        gShellTftpHiiHandle, NicName, 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
+        gShellTftpHiiHandle, NicName, 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
+        gShellTftpHiiHandle, RemoteFilePath, NicName, Status\r
+      );\r
+      goto NextHandle;\r
+    }\r
+\r
+    Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, &Data);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),\r
+        gShellTftpHiiHandle, RemoteFilePath, NicName, Status\r
+      );\r
+      goto NextHandle;\r
+    }\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
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),\r
+        gShellTftpHiiHandle, L"tftp", LocalFilePath\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
+        gShellTftpHiiHandle, LocalFilePath, Status\r
+      );\r
+    }\r
+    ShellCloseFile (&FileHandle);\r
+\r
+    NextHandle:\r
+\r
+    if (Data != NULL) {\r
+      gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (FileSize));\r
+    }\r
+\r
+    CloseProtocolAndDestroyServiceChild (\r
+      ControllerHandle,\r
+      &gEfiMtftp4ServiceBindingProtocolGuid,\r
+      &gEfiMtftp4ProtocolGuid,\r
+      Mtftp4ChildHandle\r
+      );\r
+  }\r
+\r
+  if ((UserNicName != NULL) && (NicFound == FALSE)) {\r
+    ShellPrintHiiEx (\r
+      -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),\r
+      gShellTftpHiiHandle, UserNicName\r
+    );\r
+  }\r
+\r
+  Error:\r
+\r
+  ShellCommandLineFreeVarList (CheckPackage);\r
+  if (AsciiRemoteFilePath != NULL) {\r
+    FreePool (AsciiRemoteFilePath);\r
+  }\r
+  if (Handles != NULL) {\r
+    FreePool (Handles);\r
+  }\r
+\r
+  return ShellStatus;\r
+}\r
+\r
+/**\r
+  Check and convert the UINT16 option values of the 'tftp' command\r
+\r
+  @param[in]  ValueStr  Value as an Unicode encoded string\r
+  @param[out] Value     UINT16 value\r
+\r
+  @return     TRUE      The value was returned.\r
+  @return     FALSE     A parsing error occured.\r
+**/\r
+STATIC\r
+BOOLEAN\r
+StringToUint16 (\r
+  IN   CONST CHAR16  *ValueStr,\r
+  OUT  UINT16        *Value\r
+  )\r
+{\r
+  UINTN  Val;\r
+\r
+  Val = ShellStrToUintn (ValueStr);\r
+  if (Val > MAX_UINT16) {\r
+    ShellPrintHiiEx (\r
+      -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),\r
+      gShellTftpHiiHandle, L"tftp", ValueStr\r
+    );\r
+    return FALSE;\r
+  }\r
+\r
+  *Value = Val;\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Get the name of the NIC.\r
+\r
+  @param[in]   ControllerHandle  The network physical device handle.\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
+\r
+  @return  EFI_SUCCESS  The name of the NIC was returned.\r
+  @return  Others       The creation of the child for the Managed\r
+                        Network Service failed or the opening of\r
+                        the Managed Network Protocol failed or\r
+                        the operational parameters for the\r
+                        Managed Network Protocol could not be\r
+                        read.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetNicName (\r
+  IN   EFI_HANDLE  ControllerHandle,\r
+  IN   UINTN       NicNumber,\r
+  OUT  CHAR16      *NicName\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    MnpHandle;\r
+  EFI_MANAGED_NETWORK_PROTOCOL  *Mnp;\r
+  EFI_SIMPLE_NETWORK_MODE       SnpMode;\r
+\r
+  Status = CreateServiceChildAndOpenProtocol (\r
+             ControllerHandle,\r
+             &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+             &gEfiManagedNetworkProtocolGuid,\r
+             &MnpHandle,\r
+             (VOID**)&Mnp\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);\r
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r
+    goto Error;\r
+  }\r
+\r
+  UnicodeSPrint (\r
+    NicName,\r
+    IP4_NIC_NAME_LENGTH,\r
+    SnpMode.IfType == NET_IFTYPE_ETHERNET ?\r
+    L"eth%d" :\r
+    L"unk%d" ,\r
+    NicNumber\r
+    );\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+Error:\r
+\r
+  if (MnpHandle != NULL) {\r
+    CloseProtocolAndDestroyServiceChild (\r
+      ControllerHandle,\r
+      &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+      &gEfiManagedNetworkProtocolGuid,\r
+      MnpHandle\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Create a child for the service identified by its service binding protocol GUID\r
+  and get from the child the interface of the protocol identified by its GUID.\r
+\r
+  @param[in]   ControllerHandle            Controller handle.\r
+  @param[in]   ServiceBindingProtocolGuid  Service binding protocol GUID of the\r
+                                           service to be created.\r
+  @param[in]   ProtocolGuid                GUID of the protocol to be open.\r
+  @param[out]  ChildHandle                 Address where the handler of the\r
+                                           created child is returned. NULL is\r
+                                           returned in case of error.\r
+  @param[out]  Interface                   Address where a pointer to the\r
+                                           protocol interface is returned in\r
+                                           case of success.\r
+\r
+  @return  EFI_SUCCESS  The child was created and the protocol opened.\r
+  @return  Others       Either the creation of the child or the opening\r
+                        of the protocol failed.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+CreateServiceChildAndOpenProtocol (\r
+  IN   EFI_HANDLE  ControllerHandle,\r
+  IN   EFI_GUID    *ServiceBindingProtocolGuid,\r
+  IN   EFI_GUID    *ProtocolGuid,\r
+  OUT  EFI_HANDLE  *ChildHandle,\r
+  OUT  VOID        **Interface\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  *ChildHandle = NULL;\r
+  Status = NetLibCreateServiceChild (\r
+             ControllerHandle,\r
+             gImageHandle,\r
+             ServiceBindingProtocolGuid,\r
+             ChildHandle\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->OpenProtocol (\r
+                    *ChildHandle,\r
+                    ProtocolGuid,\r
+                    Interface,\r
+                    gImageHandle,\r
+                    ControllerHandle,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      NetLibDestroyServiceChild (\r
+        ControllerHandle,\r
+        gImageHandle,\r
+        ServiceBindingProtocolGuid,\r
+        *ChildHandle\r
+        );\r
+      *ChildHandle = NULL;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Close the protocol identified by its GUID on the child handle of the service\r
+  identified by its service binding protocol GUID, then destroy the child\r
+  handle.\r
+\r
+  @param[in]  ControllerHandle            Controller handle.\r
+  @param[in]  ServiceBindingProtocolGuid  Service binding protocol GUID of the\r
+                                          service to be destroyed.\r
+  @param[in]  ProtocolGuid                GUID of the protocol to be closed.\r
+  @param[in]  ChildHandle                 Handle of the child to be destroyed.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+CloseProtocolAndDestroyServiceChild (\r
+  IN  EFI_HANDLE  ControllerHandle,\r
+  IN  EFI_GUID    *ServiceBindingProtocolGuid,\r
+  IN  EFI_GUID    *ProtocolGuid,\r
+  IN  EFI_HANDLE  ChildHandle\r
+  )\r
+{\r
+  gBS->CloseProtocol (\r
+         ChildHandle,\r
+         ProtocolGuid,\r
+         gImageHandle,\r
+         ControllerHandle\r
+         );\r
+\r
+  NetLibDestroyServiceChild (\r
+    ControllerHandle,\r
+    gImageHandle,\r
+    ServiceBindingProtocolGuid,\r
+    ChildHandle\r
+    );\r
+}\r
+\r
+/**\r
+  Worker function that gets the size in numbers of bytes of a file from a TFTP\r
+  server before to download the file.\r
+\r
+  @param[in]   Mtftp4    MTFTP4 protocol interface\r
+  @param[in]   FilePath  Path of the file, ASCII encoded\r
+  @param[out]  FileSize  Address where to store the file size in number of\r
+                         bytes.\r
+\r
+  @retval  EFI_SUCCESS      The size of the file was returned.\r
+  @retval  EFI_UNSUPPORTED  The server does not support the "tsize" option.\r
+  @retval  Others           Error when retrieving the information from the server\r
+                            (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)\r
+                            or error when parsing the response of the server.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetFileSize (\r
+  IN   EFI_MTFTP4_PROTOCOL  *Mtftp4,\r
+  IN   CONST CHAR8          *FilePath,\r
+  OUT  UINTN                *FileSize\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  EFI_MTFTP4_OPTION  ReqOpt[1];\r
+  EFI_MTFTP4_PACKET  *Packet;\r
+  UINT32             PktLen;\r
+  EFI_MTFTP4_OPTION  *TableOfOptions;\r
+  EFI_MTFTP4_OPTION  *Option;\r
+  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
+\r
+  Status = Mtftp4->GetInfo (\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
+  }\r
+\r
+  Status = Mtftp4->ParseOptions (\r
+                     Mtftp4,\r
+                     PktLen,\r
+                     Packet,\r
+                     (UINT32 *) &OptCnt,\r
+                     &TableOfOptions\r
+                     );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  Option = TableOfOptions;\r
+  while (OptCnt != 0) {\r
+    if (AsciiStrnCmp ((CHAR8 *)Option->OptionStr, "tsize", 5) == 0) {\r
+      *FileSize = AsciiStrDecimalToUintn ((CHAR8 *)Option->ValueStr);\r
+      break;\r
+    }\r
+    OptCnt--;\r
+    Option++;\r
+  }\r
+  FreePool (TableOfOptions);\r
+\r
+  if (OptCnt == 0) {\r
+    Status = EFI_UNSUPPORTED;\r
+  }\r
+\r
+Error :\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Worker function that download the data of a file from a TFTP server given\r
+  the path of the file and its size.\r
+\r
+  @param[in]   Mtftp4         MTFTP4 protocol interface\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[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
+  @retval  Others                The downloading of the file from the server failed\r
+                                 (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).\r
+\r
+**/\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
+  OUT  VOID                 **Data\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  PagesAddress;\r
+  VOID                  *Buffer;\r
+  DOWNLOAD_CONTEXT      *TftpContext;\r
+  EFI_MTFTP4_TOKEN      Mtftp4Token;\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
+  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
+\r
+  ShellPrintHiiEx (\r
+    -1, -1, NULL, STRING_TOKEN (STR_TFTP_DOWNLOADING),\r
+    gShellTftpHiiHandle, FilePath\r
+    );\r
+\r
+  Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);\r
+  ShellPrintHiiEx (\r
+    -1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF),\r
+    gShellTftpHiiHandle\r
+    );\r
+\r
+Error :\r
+\r
+  if (TftpContext == NULL) {\r
+    FreePool (TftpContext);\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
+}\r
+\r
+/**\r
+  Update the progress of a file download\r
+  This procedure is called each time a new TFTP packet is received.\r
+\r
+  @param[in]  This       MTFTP4 protocol interface\r
+  @param[in]  Token      Parameters for the download of the file\r
+  @param[in]  PacketLen  Length of the packet\r
+  @param[in]  Packet     Address of the packet\r
+\r
+  @retval  EFI_SUCCESS  All packets are accepted.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+CheckPacket (\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
+  DOWNLOAD_CONTEXT  *Context;\r
+  CHAR16            Progress[TFTP_PROGRESS_MESSAGE_SIZE];\r
+  UINT64            NbOfKb;\r
+  UINTN             Index;\r
+  UINTN             LastStep;\r
+  UINTN             Step;\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
+\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
+\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
+  if (Step <= LastStep) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete);\r
+\r
+  StrCpy (Progress, mTftpProgressFrame);\r
+  for (Index = 1; Index < Step; Index++) {\r
+    Progress[Index] = L'=';\r
+  }\r
+  Progress[Step] = L'>';\r
+\r
+  UnicodeSPrint (\r
+    Progress + (sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 1,\r
+    sizeof (Progress) - sizeof (mTftpProgressFrame),\r
+    L" %7d Kb",\r
+    NbOfKb\r
+    );\r
+  Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes;\r
+\r
+  ShellPrintEx (-1, -1, L"%s", Progress);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.c b/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.c
new file mode 100644 (file)
index 0000000..22c81b8
--- /dev/null
@@ -0,0 +1,97 @@
+/** @file\r
+  Main file for NULL named library for 'tftp' Shell command functions.\r
+\r
+  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved. <BR>\r
+  Copyright (c) 2015, ARM Ltd. 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
+\r
+**/\r
+#include "UefiShellTftpCommandLib.h"\r
+\r
+CONST CHAR16 gShellTftpFileName[] = L"ShellCommand";\r
+EFI_HANDLE gShellTftpHiiHandle = NULL;\r
+\r
+/**\r
+  Return the file name of the help text file if not using HII.\r
+\r
+  @return The string pointer to the file name.\r
+**/\r
+CONST CHAR16*\r
+EFIAPI\r
+ShellCommandGetManFileNameTftp (\r
+  VOID\r
+  )\r
+{\r
+  return gShellTftpFileName;\r
+}\r
+\r
+/**\r
+  Constructor for the Shell Tftp Command library.\r
+\r
+  Install the handlers for Tftp UEFI Shell command.\r
+\r
+  @param ImageHandle            The image handle of the process.\r
+  @param SystemTable            The EFI System Table pointer.\r
+\r
+  @retval EFI_SUCCESS           The Shell command handlers were installed sucessfully.\r
+  @retval EFI_UNSUPPORTED       The Shell level required was not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellTftpCommandLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  gShellTftpHiiHandle = NULL;\r
+\r
+  //\r
+  // check our bit of the profiles mask\r
+  //\r
+  if ((PcdGet8 (PcdShellProfileMask) & BIT3) == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  gShellTftpHiiHandle = HiiAddPackages (\r
+                          &gShellTftpHiiGuid, gImageHandle,\r
+                          UefiShellTftpCommandLibStrings, NULL\r
+                          );\r
+  if (gShellTftpHiiHandle == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  //\r
+  // Install our Shell command handler\r
+  //\r
+  ShellCommandRegisterCommandName (\r
+     L"tftp", ShellCommandRunTftp, ShellCommandGetManFileNameTftp, 0,\r
+     L"tftp", TRUE , gShellTftpHiiHandle, STRING_TOKEN (STR_GET_HELP_TFTP)\r
+     );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Destructor for the library.  free any resources.\r
+\r
+  @param ImageHandle            The image handle of the process.\r
+  @param SystemTable            The EFI System Table pointer.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellTftpCommandLibDestructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  if (gShellTftpHiiHandle != NULL) {\r
+    HiiRemovePackages (gShellTftpHiiHandle);\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.h b/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.h
new file mode 100644 (file)
index 0000000..a73b86c
--- /dev/null
@@ -0,0 +1,63 @@
+/** @file\r
+  header file for NULL named library for 'tftp' Shell command functions.\r
+\r
+  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved. <BR>\r
+  Copyright (c) 2015, ARM Ltd. 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
+\r
+**/\r
+\r
+#ifndef _UEFI_SHELL_TFTP_COMMAND_LIB_H_\r
+#define _UEFI_SHELL_TFTP_COMMAND_LIB_H_\r
+\r
+#include <Uefi.h>\r
+#include <ShellBase.h>\r
+\r
+#include <Guid/ShellLibHiiGuid.h>\r
+#include <Guid/NicIp4ConfigNvData.h>\r
+\r
+#include <Protocol/ServiceBinding.h>\r
+#include <Protocol/Mtftp4.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/ShellCommandLib.h>\r
+#include <Library/ShellLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/NetLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+extern EFI_HANDLE gShellTftpHiiHandle;\r
+\r
+typedef struct {\r
+  UINT64  FileSize;\r
+  UINT64  DownloadedNbOfBytes;\r
+  UINT64  LastReportedNbOfBytes;\r
+} DOWNLOAD_CONTEXT;\r
+\r
+/**\r
+  Function for 'tftp' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunTftp (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  );\r
+\r
+#endif /* _UEFI_SHELL_TFTP_COMMAND_LIB_H_ */\r
diff --git a/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf b/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
new file mode 100644 (file)
index 0000000..43b367d
--- /dev/null
@@ -0,0 +1,61 @@
+##  @file\r
+# Provides Shell 'tftp' command functions\r
+#\r
+# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved. <BR>\r
+# Copyright (c) 2015, ARM Ltd. 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
+#  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
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = UefiShellTftpCommandLib\r
+  FILE_GUID                      = D2B61A25-9835-4E5D-906A-15615E1FF668\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|UEFI_APPLICATION UEFI_DRIVER\r
+  CONSTRUCTOR                    = ShellTftpCommandLibConstructor\r
+  DESTRUCTOR                     = ShellTftpCommandLibDestructor\r
+\r
+[Sources.common]\r
+  UefiShellTftpCommandLib.uni\r
+  UefiShellTftpCommandLib.c\r
+  UefiShellTftpCommandLib.h\r
+  Tftp.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  ShellCommandLib\r
+  ShellLib\r
+  UefiLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  PcdLib\r
+  HiiLib\r
+  FileHandleLib\r
+  NetLib\r
+\r
+[Pcd]\r
+  gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES\r
+\r
+[Protocols]\r
+  gEfiManagedNetworkServiceBindingProtocolGuid   ## CONSUMES\r
+  gEfiMtftp4ServiceBindingProtocolGuid           ## CONSUMES\r
+\r
+[Guids]\r
+  gShellTftpHiiGuid                              ## CONSUMES ## HII\r
diff --git a/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.uni b/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.uni
new file mode 100644 (file)
index 0000000..607a360
Binary files /dev/null and b/ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.uni differ
index 453487653a5af1e3c435dda0ddfbb3b016781d5d..b2f632601eb17b79bdb7b433ece88d078e22b33c 100644 (file)
@@ -53,6 +53,7 @@
   gShellLevel2HiiGuid             = {0xf95a7ccc, 0x4c55, 0x4426, {0xa7, 0xb4, 0xdc, 0x89, 0x61, 0x95, 0xb, 0xae}}\r
   gShellLevel3HiiGuid             = {0x4344558d, 0x4ef9, 0x4725, {0xb1, 0xe4, 0x33, 0x76, 0xe8, 0xd6, 0x97, 0x4f}}\r
   gShellNetwork1HiiGuid           = {0xf3d301bb, 0xf4a5, 0x45a8, {0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae}}\r
+  gShellTftpHiiGuid               = {0x738a9314, 0x82c1, 0x4592, {0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}}\r
   gShellBcfgHiiGuid               = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6}}\r
 \r
 [Protocols]\r
index 9d54acc81f380a597ed9d9ecb7c3c7cc259d3f4a..c2ce4f9ab365637aee17cad1b6882e234575ddb2 100644 (file)
@@ -98,6 +98,9 @@
 !ifdef $(INCLUDE_DP)\r
       NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf\r
 !endif #$(INCLUDE_DP)\r
+!ifdef $(INCLUDE_TFTP_COMMAND)\r
+      NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf\r
+!endif #$(INCLUDE_TFTP_COMMAND)\r
 !endif #$(NO_SHELL_PROFILES)\r
   }\r
 \r