2 The implementation for the 'tftp' Shell command.
4 Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
5 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>
6 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32
14 EFI_HII_HANDLE mTftpHiiHandle
;
17 Constant strings and definitions related to the message indicating the amount of
18 progress in the downloading of a TFTP file.
21 // Frame for the progression slider
22 STATIC CONST CHAR16 mTftpProgressFrame
[] = L
"[ ]";
24 // Number of steps in the progression slider
25 #define TFTP_PROGRESS_SLIDER_STEPS ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3)
27 // Size in number of characters plus one (final zero) of the message to
28 // indicate the progress of a TFTP download. The format is "[(progress slider:
29 // 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There
30 // are thus the number of characters in mTftpProgressFrame[] plus 11 characters
31 // (2 // spaces, "Kb" and seven characters for the number of KBytes).
32 #define TFTP_PROGRESS_MESSAGE_SIZE ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) + 12)
34 // String to delete the TFTP progress message to be able to update it :
35 // (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'
36 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";
39 SHELL_FILE_HANDLE mFileHandle
;
41 // Path of the local file, Unicode encoded
42 CONST CHAR16
*mLocalFilePath
;
45 Check and convert the UINT16 option values of the 'tftp' command
47 @param[in] ValueStr Value as an Unicode encoded string
48 @param[out] Value UINT16 value
50 @return TRUE The value was returned.
51 @return FALSE A parsing error occurred.
56 IN CONST CHAR16
*ValueStr
,
61 Get the name of the NIC.
63 @param[in] ControllerHandle The network physical device handle.
64 @param[in] NicNumber The network physical device number.
65 @param[out] NicName Address where to store the NIC name.
66 The memory area has to be at least
67 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
70 @return EFI_SUCCESS The name of the NIC was returned.
71 @return Others The creation of the child for the Managed
72 Network Service failed or the opening of
73 the Managed Network Protocol failed or
74 the operational parameters for the
75 Managed Network Protocol could not be
81 IN EFI_HANDLE ControllerHandle
,
87 Create a child for the service identified by its service binding protocol GUID
88 and get from the child the interface of the protocol identified by its GUID.
90 @param[in] ControllerHandle Controller handle.
91 @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
92 service to be created.
93 @param[in] ProtocolGuid GUID of the protocol to be open.
94 @param[out] ChildHandle Address where the handler of the
95 created child is returned. NULL is
96 returned in case of error.
97 @param[out] Interface Address where a pointer to the
98 protocol interface is returned in
101 @return EFI_SUCCESS The child was created and the protocol opened.
102 @return Others Either the creation of the child or the opening
103 of the protocol failed.
107 CreateServiceChildAndOpenProtocol (
108 IN EFI_HANDLE ControllerHandle
,
109 IN EFI_GUID
*ServiceBindingProtocolGuid
,
110 IN EFI_GUID
*ProtocolGuid
,
111 OUT EFI_HANDLE
*ChildHandle
,
116 Close the protocol identified by its GUID on the child handle of the service
117 identified by its service binding protocol GUID, then destroy the child
120 @param[in] ControllerHandle Controller handle.
121 @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
122 service to be destroyed.
123 @param[in] ProtocolGuid GUID of the protocol to be closed.
124 @param[in] ChildHandle Handle of the child to be destroyed.
129 CloseProtocolAndDestroyServiceChild (
130 IN EFI_HANDLE ControllerHandle
,
131 IN EFI_GUID
*ServiceBindingProtocolGuid
,
132 IN EFI_GUID
*ProtocolGuid
,
133 IN EFI_HANDLE ChildHandle
137 Worker function that gets the size in numbers of bytes of a file from a TFTP
138 server before to download the file.
140 @param[in] Mtftp4 MTFTP4 protocol interface
141 @param[in] FilePath Path of the file, ASCII encoded
142 @param[out] FileSize Address where to store the file size in number of
145 @retval EFI_SUCCESS The size of the file was returned.
146 @retval EFI_UNSUPPORTED The server does not support the "tsize" option.
147 @retval Others Error when retrieving the information from the server
148 (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)
149 or error when parsing the response of the server.
154 IN EFI_MTFTP4_PROTOCOL
*Mtftp4
,
155 IN CONST CHAR8
*FilePath
,
160 Worker function that download the data of a file from a TFTP server given
161 the path of the file and its size.
163 @param[in] Mtftp4 MTFTP4 protocol interface
164 @param[in] FilePath Path of the file, Unicode encoded
165 @param[in] AsciiFilePath Path of the file, ASCII encoded
166 @param[in] FileSize Size of the file in number of bytes
167 @param[in] BlockSize Value of the TFTP blksize option
168 @param[in] WindowSize Value of the TFTP window size option
170 @retval EFI_SUCCESS The file was downloaded.
171 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
172 @retval Others The downloading of the file from the server failed
173 (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).
179 IN EFI_MTFTP4_PROTOCOL
*Mtftp4
,
180 IN CONST CHAR16
*FilePath
,
181 IN CONST CHAR8
*AsciiFilePath
,
188 Update the progress of a file download
189 This procedure is called each time a new TFTP packet is received.
191 @param[in] This MTFTP4 protocol interface
192 @param[in] Token Parameters for the download of the file
193 @param[in] PacketLen Length of the packet
194 @param[in] Packet Address of the packet
196 @retval EFI_SUCCESS All packets are accepted.
203 IN EFI_MTFTP4_PROTOCOL
*This
,
204 IN EFI_MTFTP4_TOKEN
*Token
,
206 IN EFI_MTFTP4_PACKET
*Packet
209 EFI_MTFTP4_CONFIG_DATA DefaultMtftp4ConfigData
= {
210 TRUE
, // Use default setting
213 }, // StationIp - Not relevant as UseDefaultSetting=TRUE
216 }, // SubnetMask - Not relevant as UseDefaultSetting=TRUE
217 0, // LocalPort - Automatically assigned port number.
220 }, // GatewayIp - Not relevant as UseDefaultSetting=TRUE
223 }, // ServerIp - Not known yet
224 69, // InitialServerPort - Standard TFTP server port
225 6, // TryCount - The number of times to transmit request packets and wait for a response.
226 4 // TimeoutValue - Retransmission timeout in seconds.
229 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
230 { L
"-i", TypeValue
},
231 { L
"-l", TypeValue
},
232 { L
"-r", TypeValue
},
233 { L
"-c", TypeValue
},
234 { L
"-t", TypeValue
},
235 { L
"-s", TypeValue
},
236 { L
"-w", TypeValue
},
241 /// The default block size (512) of tftp is defined in the RFC1350.
243 #define MTFTP_DEFAULT_BLKSIZE 512
245 /// The valid range of block size option is defined in the RFC2348.
247 #define MTFTP_MIN_BLKSIZE 8
248 #define MTFTP_MAX_BLKSIZE 65464
250 /// The default windowsize (1) of tftp.
252 #define MTFTP_DEFAULT_WINDOWSIZE 1
254 /// The valid range of window size option.
255 /// Note that: RFC 7440 does not mention max window size value, but for the
256 /// stability reason, the value is limited to 64.
258 #define MTFTP_MIN_WINDOWSIZE 1
259 #define MTFTP_MAX_WINDOWSIZE 64
262 Function for 'tftp' command.
264 @param[in] ImageHandle Handle to the Image (NULL if Internal).
265 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
267 @return SHELL_SUCCESS The 'tftp' command completed successfully.
268 @return SHELL_ABORTED The Shell Library initialization failed.
269 @return SHELL_INVALID_PARAMETER At least one of the command's arguments is
271 @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
272 @return SHELL_NOT_FOUND Network Interface Card not found or server
278 IN EFI_HANDLE ImageHandle
,
279 IN EFI_SYSTEM_TABLE
*SystemTable
282 SHELL_STATUS ShellStatus
;
284 LIST_ENTRY
*CheckPackage
;
285 CHAR16
*ProblemParam
;
287 CONST CHAR16
*UserNicName
;
289 CONST CHAR16
*ValueStr
;
290 CONST CHAR16
*RemoteFilePath
;
291 CHAR8
*AsciiRemoteFilePath
;
293 CONST CHAR16
*Walker
;
294 EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData
;
298 CHAR16 NicName
[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
];
299 EFI_HANDLE ControllerHandle
;
300 EFI_HANDLE Mtftp4ChildHandle
;
301 EFI_MTFTP4_PROTOCOL
*Mtftp4
;
306 ShellStatus
= SHELL_INVALID_PARAMETER
;
309 AsciiRemoteFilePath
= NULL
;
312 BlockSize
= MTFTP_DEFAULT_BLKSIZE
;
313 WindowSize
= MTFTP_DEFAULT_WINDOWSIZE
;
316 // Initialize the Shell library (we must be in non-auto-init...)
318 Status
= ShellInitialize ();
319 if (EFI_ERROR (Status
)) {
320 ASSERT_EFI_ERROR (Status
);
321 return SHELL_ABORTED
;
325 // Parse the command line.
327 Status
= ShellCommandLineParse (ParamList
, &CheckPackage
, &ProblemParam
, TRUE
);
328 if (EFI_ERROR (Status
)) {
329 if ((Status
== EFI_VOLUME_CORRUPTED
) &&
330 (ProblemParam
!= NULL
))
336 STRING_TOKEN (STR_GEN_PROBLEM
),
341 FreePool (ProblemParam
);
350 // Check the number of parameters
352 ParamCount
= ShellCommandLineGetCount (CheckPackage
);
353 if (ParamCount
> 4) {
358 STRING_TOKEN (STR_GEN_TOO_MANY
),
365 if (ParamCount
< 3) {
370 STRING_TOKEN (STR_GEN_TOO_FEW
),
377 CopyMem (&Mtftp4ConfigData
, &DefaultMtftp4ConfigData
, sizeof (EFI_MTFTP4_CONFIG_DATA
));
380 // Check the host IPv4 address
382 ValueStr
= ShellCommandLineGetRawValue (CheckPackage
, 1);
383 Status
= NetLibStrToIp4 (ValueStr
, &Mtftp4ConfigData
.ServerIp
);
384 if (EFI_ERROR (Status
)) {
389 STRING_TOKEN (STR_GEN_PARAM_INV
),
397 RemoteFilePath
= ShellCommandLineGetRawValue (CheckPackage
, 2);
398 ASSERT (RemoteFilePath
!= NULL
);
399 FilePathSize
= StrLen (RemoteFilePath
) + 1;
400 AsciiRemoteFilePath
= AllocatePool (FilePathSize
);
401 if (AsciiRemoteFilePath
== NULL
) {
402 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
406 UnicodeStrToAsciiStrS (RemoteFilePath
, AsciiRemoteFilePath
, FilePathSize
);
408 if (ParamCount
== 4) {
409 mLocalFilePath
= ShellCommandLineGetRawValue (CheckPackage
, 3);
411 Walker
= RemoteFilePath
+ StrLen (RemoteFilePath
);
412 while ((--Walker
) >= RemoteFilePath
) {
413 if ((*Walker
== L
'\\') ||
420 mLocalFilePath
= Walker
+ 1;
424 // Get the name of the Network Interface Card to be used if any.
426 UserNicName
= ShellCommandLineGetValue (CheckPackage
, L
"-i");
428 ValueStr
= ShellCommandLineGetValue (CheckPackage
, L
"-l");
429 if (ValueStr
!= NULL
) {
430 if (!StringToUint16 (ValueStr
, &Mtftp4ConfigData
.LocalPort
)) {
435 ValueStr
= ShellCommandLineGetValue (CheckPackage
, L
"-r");
436 if (ValueStr
!= NULL
) {
437 if (!StringToUint16 (ValueStr
, &Mtftp4ConfigData
.InitialServerPort
)) {
442 ValueStr
= ShellCommandLineGetValue (CheckPackage
, L
"-c");
443 if (ValueStr
!= NULL
) {
444 if (!StringToUint16 (ValueStr
, &Mtftp4ConfigData
.TryCount
)) {
448 if (Mtftp4ConfigData
.TryCount
== 0) {
449 Mtftp4ConfigData
.TryCount
= 6;
453 ValueStr
= ShellCommandLineGetValue (CheckPackage
, L
"-t");
454 if (ValueStr
!= NULL
) {
455 if (!StringToUint16 (ValueStr
, &Mtftp4ConfigData
.TimeoutValue
)) {
459 if (Mtftp4ConfigData
.TimeoutValue
== 0) {
464 STRING_TOKEN (STR_GEN_PARAM_INV
),
473 ValueStr
= ShellCommandLineGetValue (CheckPackage
, L
"-s");
474 if (ValueStr
!= NULL
) {
475 if (!StringToUint16 (ValueStr
, &BlockSize
)) {
479 if ((BlockSize
< MTFTP_MIN_BLKSIZE
) || (BlockSize
> MTFTP_MAX_BLKSIZE
)) {
484 STRING_TOKEN (STR_GEN_PARAM_INV
),
493 ValueStr
= ShellCommandLineGetValue (CheckPackage
, L
"-w");
494 if (ValueStr
!= NULL
) {
495 if (!StringToUint16 (ValueStr
, &WindowSize
)) {
499 if ((WindowSize
< MTFTP_MIN_WINDOWSIZE
) || (WindowSize
> MTFTP_MAX_WINDOWSIZE
)) {
504 STRING_TOKEN (STR_GEN_PARAM_INV
),
514 // Locate all MTFTP4 Service Binding protocols
516 ShellStatus
= SHELL_NOT_FOUND
;
517 Status
= gBS
->LocateHandleBuffer (
519 &gEfiManagedNetworkServiceBindingProtocolGuid
,
524 if (EFI_ERROR (Status
) || (HandleCount
== 0)) {
529 STRING_TOKEN (STR_TFTP_ERR_NO_NIC
),
536 (NicNumber
< HandleCount
) && (ShellStatus
!= SHELL_SUCCESS
);
539 ControllerHandle
= Handles
[NicNumber
];
541 Status
= GetNicName (ControllerHandle
, NicNumber
, NicName
);
542 if (EFI_ERROR (Status
)) {
547 STRING_TOKEN (STR_TFTP_ERR_NIC_NAME
),
555 if (UserNicName
!= NULL
) {
556 if (StrCmp (NicName
, UserNicName
) != 0) {
563 Status
= CreateServiceChildAndOpenProtocol (
565 &gEfiMtftp4ServiceBindingProtocolGuid
,
566 &gEfiMtftp4ProtocolGuid
,
570 if (EFI_ERROR (Status
)) {
575 STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL
),
583 Status
= Mtftp4
->Configure (Mtftp4
, &Mtftp4ConfigData
);
584 if (EFI_ERROR (Status
)) {
589 STRING_TOKEN (STR_TFTP_ERR_CONFIGURE
),
597 Status
= GetFileSize (Mtftp4
, AsciiRemoteFilePath
, &FileSize
);
598 if (EFI_ERROR (Status
)) {
603 STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE
),
612 Status
= DownloadFile (Mtftp4
, RemoteFilePath
, AsciiRemoteFilePath
, FileSize
, BlockSize
, WindowSize
);
613 if (EFI_ERROR (Status
)) {
618 STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD
),
627 ShellStatus
= SHELL_SUCCESS
;
631 CloseProtocolAndDestroyServiceChild (
633 &gEfiMtftp4ServiceBindingProtocolGuid
,
634 &gEfiMtftp4ProtocolGuid
,
639 if ((UserNicName
!= NULL
) && (!NicFound
)) {
644 STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND
),
652 ShellCommandLineFreeVarList (CheckPackage
);
653 if (AsciiRemoteFilePath
!= NULL
) {
654 FreePool (AsciiRemoteFilePath
);
657 if (Handles
!= NULL
) {
661 if ((ShellStatus
!= SHELL_SUCCESS
) && (EFI_ERROR (Status
))) {
662 ShellStatus
= Status
& ~MAX_BIT
;
669 Check and convert the UINT16 option values of the 'tftp' command
671 @param[in] ValueStr Value as an Unicode encoded string
672 @param[out] Value UINT16 value
674 @return TRUE The value was returned.
675 @return FALSE A parsing error occurred.
680 IN CONST CHAR16
*ValueStr
,
686 Val
= ShellStrToUintn (ValueStr
);
687 if (Val
> MAX_UINT16
) {
692 STRING_TOKEN (STR_GEN_PARAM_INV
),
700 *Value
= (UINT16
)Val
;
705 Get the name of the NIC.
707 @param[in] ControllerHandle The network physical device handle.
708 @param[in] NicNumber The network physical device number.
709 @param[out] NicName Address where to store the NIC name.
710 The memory area has to be at least
711 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
714 @return EFI_SUCCESS The name of the NIC was returned.
715 @return Others The creation of the child for the Managed
716 Network Service failed or the opening of
717 the Managed Network Protocol failed or
718 the operational parameters for the
719 Managed Network Protocol could not be
725 IN EFI_HANDLE ControllerHandle
,
731 EFI_HANDLE MnpHandle
;
732 EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
;
733 EFI_SIMPLE_NETWORK_MODE SnpMode
;
735 Status
= CreateServiceChildAndOpenProtocol (
737 &gEfiManagedNetworkServiceBindingProtocolGuid
,
738 &gEfiManagedNetworkProtocolGuid
,
742 if (EFI_ERROR (Status
)) {
746 Status
= Mnp
->GetModeData (Mnp
, NULL
, &SnpMode
);
747 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
753 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
,
754 SnpMode
.IfType
== NET_IFTYPE_ETHERNET
?
760 Status
= EFI_SUCCESS
;
764 if (MnpHandle
!= NULL
) {
765 CloseProtocolAndDestroyServiceChild (
767 &gEfiManagedNetworkServiceBindingProtocolGuid
,
768 &gEfiManagedNetworkProtocolGuid
,
777 Create a child for the service identified by its service binding protocol GUID
778 and get from the child the interface of the protocol identified by its GUID.
780 @param[in] ControllerHandle Controller handle.
781 @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
782 service to be created.
783 @param[in] ProtocolGuid GUID of the protocol to be open.
784 @param[out] ChildHandle Address where the handler of the
785 created child is returned. NULL is
786 returned in case of error.
787 @param[out] Interface Address where a pointer to the
788 protocol interface is returned in
791 @return EFI_SUCCESS The child was created and the protocol opened.
792 @return Others Either the creation of the child or the opening
793 of the protocol failed.
797 CreateServiceChildAndOpenProtocol (
798 IN EFI_HANDLE ControllerHandle
,
799 IN EFI_GUID
*ServiceBindingProtocolGuid
,
800 IN EFI_GUID
*ProtocolGuid
,
801 OUT EFI_HANDLE
*ChildHandle
,
808 Status
= NetLibCreateServiceChild (
811 ServiceBindingProtocolGuid
,
814 if (!EFI_ERROR (Status
)) {
815 Status
= gBS
->OpenProtocol (
821 EFI_OPEN_PROTOCOL_GET_PROTOCOL
823 if (EFI_ERROR (Status
)) {
824 NetLibDestroyServiceChild (
827 ServiceBindingProtocolGuid
,
838 Close the protocol identified by its GUID on the child handle of the service
839 identified by its service binding protocol GUID, then destroy the child
842 @param[in] ControllerHandle Controller handle.
843 @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
844 service to be destroyed.
845 @param[in] ProtocolGuid GUID of the protocol to be closed.
846 @param[in] ChildHandle Handle of the child to be destroyed.
851 CloseProtocolAndDestroyServiceChild (
852 IN EFI_HANDLE ControllerHandle
,
853 IN EFI_GUID
*ServiceBindingProtocolGuid
,
854 IN EFI_GUID
*ProtocolGuid
,
855 IN EFI_HANDLE ChildHandle
865 NetLibDestroyServiceChild (
868 ServiceBindingProtocolGuid
,
874 Worker function that gets the size in numbers of bytes of a file from a TFTP
875 server before to download the file.
877 @param[in] Mtftp4 MTFTP4 protocol interface
878 @param[in] FilePath Path of the file, ASCII encoded
879 @param[out] FileSize Address where to store the file size in number of
882 @retval EFI_SUCCESS The size of the file was returned.
883 @retval EFI_UNSUPPORTED The server does not support the "tsize" option.
884 @retval Others Error when retrieving the information from the server
885 (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)
886 or error when parsing the response of the server.
891 IN EFI_MTFTP4_PROTOCOL
*Mtftp4
,
892 IN CONST CHAR8
*FilePath
,
897 EFI_MTFTP4_OPTION ReqOpt
[1];
898 EFI_MTFTP4_PACKET
*Packet
;
900 EFI_MTFTP4_OPTION
*TableOfOptions
;
901 EFI_MTFTP4_OPTION
*Option
;
905 ReqOpt
[0].OptionStr
= (UINT8
*)"tsize";
908 ReqOpt
[0].ValueStr
= OptBuf
;
910 Status
= Mtftp4
->GetInfo (
921 if (EFI_ERROR (Status
)) {
925 Status
= Mtftp4
->ParseOptions (
932 if (EFI_ERROR (Status
)) {
936 Option
= TableOfOptions
;
937 while (OptCnt
!= 0) {
938 if (AsciiStrnCmp ((CHAR8
*)Option
->OptionStr
, "tsize", 5) == 0) {
939 *FileSize
= AsciiStrDecimalToUintn ((CHAR8
*)Option
->ValueStr
);
947 FreePool (TableOfOptions
);
950 Status
= EFI_UNSUPPORTED
;
959 Worker function that download the data of a file from a TFTP server given
960 the path of the file and its size.
962 @param[in] Mtftp4 MTFTP4 protocol interface
963 @param[in] FilePath Path of the file, Unicode encoded
964 @param[in] AsciiFilePath Path of the file, ASCII encoded
965 @param[in] FileSize Size of the file in number of bytes
966 @param[in] BlockSize Value of the TFTP blksize option
967 @param[in] WindowSize Value of the TFTP window size option
969 @retval EFI_SUCCESS The file was downloaded.
970 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
971 @retval Others The downloading of the file from the server failed
972 (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).
978 IN EFI_MTFTP4_PROTOCOL
*Mtftp4
,
979 IN CONST CHAR16
*FilePath
,
980 IN CONST CHAR8
*AsciiFilePath
,
987 DOWNLOAD_CONTEXT
*TftpContext
;
988 EFI_MTFTP4_TOKEN Mtftp4Token
;
989 UINT8 BlksizeBuf
[10];
990 UINT8 WindowsizeBuf
[10];
992 ZeroMem (&Mtftp4Token
, sizeof (EFI_MTFTP4_TOKEN
));
994 TftpContext
= AllocatePool (sizeof (DOWNLOAD_CONTEXT
));
995 if (TftpContext
== NULL
) {
996 Status
= EFI_OUT_OF_RESOURCES
;
1000 TftpContext
->FileSize
= FileSize
;
1001 TftpContext
->DownloadedNbOfBytes
= 0;
1002 TftpContext
->LastReportedNbOfBytes
= 0;
1004 Mtftp4Token
.Filename
= (UINT8
*)AsciiFilePath
;
1005 Mtftp4Token
.CheckPacket
= CheckPacket
;
1006 Mtftp4Token
.Context
= (VOID
*)TftpContext
;
1007 Mtftp4Token
.OptionCount
= 0;
1008 Mtftp4Token
.OptionList
= AllocatePool (sizeof (EFI_MTFTP4_OPTION
) * 2);
1009 if (Mtftp4Token
.OptionList
== NULL
) {
1010 Status
= EFI_OUT_OF_RESOURCES
;
1014 if (BlockSize
!= MTFTP_DEFAULT_BLKSIZE
) {
1015 Mtftp4Token
.OptionList
[Mtftp4Token
.OptionCount
].OptionStr
= (UINT8
*)"blksize";
1016 AsciiSPrint ((CHAR8
*)BlksizeBuf
, sizeof (BlksizeBuf
), "%d", BlockSize
);
1017 Mtftp4Token
.OptionList
[Mtftp4Token
.OptionCount
].ValueStr
= BlksizeBuf
;
1018 Mtftp4Token
.OptionCount
++;
1021 if (WindowSize
!= MTFTP_DEFAULT_WINDOWSIZE
) {
1022 Mtftp4Token
.OptionList
[Mtftp4Token
.OptionCount
].OptionStr
= (UINT8
*)"windowsize";
1023 AsciiSPrint ((CHAR8
*)WindowsizeBuf
, sizeof (WindowsizeBuf
), "%d", WindowSize
);
1024 Mtftp4Token
.OptionList
[Mtftp4Token
.OptionCount
].ValueStr
= WindowsizeBuf
;
1025 Mtftp4Token
.OptionCount
++;
1032 STRING_TOKEN (STR_TFTP_DOWNLOADING
),
1040 if (!EFI_ERROR (ShellFileExists (mLocalFilePath
))) {
1041 ShellDeleteFileByName (mLocalFilePath
);
1044 Status
= ShellOpenFileByName (
1047 EFI_FILE_MODE_CREATE
|
1048 EFI_FILE_MODE_WRITE
|
1052 if (EFI_ERROR (Status
)) {
1057 STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
),
1065 Status
= Mtftp4
->ReadFile (Mtftp4
, &Mtftp4Token
);
1070 STRING_TOKEN (STR_GEN_CRLF
),
1077 ShellCloseFile (&mFileHandle
);
1080 if (TftpContext
!= NULL
) {
1081 FreePool (TftpContext
);
1084 if (Mtftp4Token
.OptionList
!= NULL
) {
1085 FreePool (Mtftp4Token
.OptionList
);
1092 Update the progress of a file download
1093 This procedure is called each time a new TFTP packet is received.
1095 @param[in] This MTFTP4 protocol interface
1096 @param[in] Token Parameters for the download of the file
1097 @param[in] PacketLen Length of the packet
1098 @param[in] Packet Address of the packet
1100 @retval EFI_SUCCESS All packets are accepted.
1107 IN EFI_MTFTP4_PROTOCOL
*This
,
1108 IN EFI_MTFTP4_TOKEN
*Token
,
1109 IN UINT16 PacketLen
,
1110 IN EFI_MTFTP4_PACKET
*Packet
1113 DOWNLOAD_CONTEXT
*Context
;
1114 CHAR16 Progress
[TFTP_PROGRESS_MESSAGE_SIZE
];
1122 if ((NTOHS (Packet
->OpCode
)) != EFI_MTFTP4_OPCODE_DATA
) {
1126 Context
= (DOWNLOAD_CONTEXT
*)Token
->Context
;
1129 // The data in the packet are prepended with two UINT16 :
1130 // . OpCode = EFI_MTFTP4_OPCODE_DATA
1131 // . Block = the number of this block of data
1133 DownloadLen
= (UINTN
)PacketLen
- sizeof (Packet
->OpCode
) - sizeof (Packet
->Data
.Block
);
1135 ShellSetFilePosition (mFileHandle
, Context
->DownloadedNbOfBytes
);
1136 Status
= ShellWriteFile (mFileHandle
, &DownloadLen
, Packet
->Data
.Data
);
1137 if (EFI_ERROR (Status
)) {
1138 if (Context
->DownloadedNbOfBytes
> 0) {
1143 STRING_TOKEN (STR_GEN_CRLF
),
1152 STRING_TOKEN (STR_TFTP_ERR_WRITE
),
1160 if (Context
->DownloadedNbOfBytes
== 0) {
1161 ShellPrintEx (-1, -1, L
"%s 0 Kb", mTftpProgressFrame
);
1164 Context
->DownloadedNbOfBytes
+= DownloadLen
;
1165 NbOfKb
= Context
->DownloadedNbOfBytes
/ 1024;
1167 Progress
[0] = L
'\0';
1168 LastStep
= (Context
->LastReportedNbOfBytes
* TFTP_PROGRESS_SLIDER_STEPS
) / Context
->FileSize
;
1169 Step
= (Context
->DownloadedNbOfBytes
* TFTP_PROGRESS_SLIDER_STEPS
) / Context
->FileSize
;
1171 if (Step
<= LastStep
) {
1175 ShellPrintEx (-1, -1, L
"%s", mTftpProgressDelete
);
1177 Status
= StrCpyS (Progress
, TFTP_PROGRESS_MESSAGE_SIZE
, mTftpProgressFrame
);
1178 if (EFI_ERROR (Status
)) {
1182 for (Index
= 1; Index
< Step
; Index
++) {
1183 Progress
[Index
] = L
'=';
1186 Progress
[Step
] = L
'>';
1189 Progress
+ (sizeof (mTftpProgressFrame
) / sizeof (CHAR16
)) - 1,
1190 sizeof (Progress
) - sizeof (mTftpProgressFrame
),
1194 Context
->LastReportedNbOfBytes
= Context
->DownloadedNbOfBytes
;
1196 ShellPrintEx (-1, -1, L
"%s", Progress
);
1202 Retrieve HII package list from ImageHandle and publish to HII database.
1204 @param ImageHandle The image handle of the process.
1209 InitializeHiiPackage (
1210 EFI_HANDLE ImageHandle
1214 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
1215 EFI_HII_HANDLE HiiHandle
;
1218 // Retrieve HII package list from ImageHandle
1220 Status
= gBS
->OpenProtocol (
1222 &gEfiHiiPackageListProtocolGuid
,
1223 (VOID
**)&PackageList
,
1226 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1228 ASSERT_EFI_ERROR (Status
);
1229 if (EFI_ERROR (Status
)) {
1234 // Publish HII package list to HII Database.
1236 Status
= gHiiDatabase
->NewPackageList (
1242 ASSERT_EFI_ERROR (Status
);
1243 if (EFI_ERROR (Status
)) {