]>
Commit | Line | Data |
---|---|---|
68074260 RC |
1 | /** @file\r |
2 | The implementation for the 'tftp' Shell command.\r | |
3 | \r | |
4 | Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r | |
ba0014b9 | 5 | Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>\r |
6add86ab | 6 | (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r |
68074260 | 7 | \r |
56ba3746 | 8 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
68074260 RC |
9 | **/\r |
10 | \r | |
09610023 | 11 | #include "Tftp.h"\r |
68074260 | 12 | \r |
47d20b54 MK |
13 | #define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32\r |
14 | EFI_HII_HANDLE mTftpHiiHandle;\r | |
6add86ab | 15 | \r |
68074260 RC |
16 | /*\r |
17 | Constant strings and definitions related to the message indicating the amount of\r | |
f16bd394 | 18 | progress in the downloading of a TFTP file.\r |
68074260 RC |
19 | */\r |
20 | \r | |
21 | // Frame for the progression slider\r | |
47d20b54 | 22 | STATIC CONST CHAR16 mTftpProgressFrame[] = L"[ ]";\r |
68074260 RC |
23 | \r |
24 | // Number of steps in the progression slider\r | |
25 | #define TFTP_PROGRESS_SLIDER_STEPS ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 3)\r | |
26 | \r | |
27 | // Size in number of characters plus one (final zero) of the message to\r | |
28 | // indicate the progress of a TFTP download. The format is "[(progress slider:\r | |
29 | // 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There\r | |
30 | // are thus the number of characters in mTftpProgressFrame[] plus 11 characters\r | |
31 | // (2 // spaces, "Kb" and seven characters for the number of KBytes).\r | |
32 | #define TFTP_PROGRESS_MESSAGE_SIZE ((sizeof (mTftpProgressFrame) / sizeof (CHAR16)) + 12)\r | |
33 | \r | |
34 | // String to delete the TFTP progress message to be able to update it :\r | |
35 | // (TFTP_PROGRESS_MESSAGE_SIZE-1) '\b'\r | |
47d20b54 | 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";\r |
68074260 | 37 | \r |
b85c8fb4 | 38 | // Local File Handle\r |
47d20b54 | 39 | SHELL_FILE_HANDLE mFileHandle;\r |
b85c8fb4 AL |
40 | \r |
41 | // Path of the local file, Unicode encoded\r | |
47d20b54 | 42 | CONST CHAR16 *mLocalFilePath;\r |
b85c8fb4 | 43 | \r |
0fcf66a4 QS |
44 | /**\r |
45 | Check and convert the UINT16 option values of the 'tftp' command\r | |
46 | \r | |
47 | @param[in] ValueStr Value as an Unicode encoded string\r | |
48 | @param[out] Value UINT16 value\r | |
49 | \r | |
50 | @return TRUE The value was returned.\r | |
f16bd394 | 51 | @return FALSE A parsing error occurred.\r |
0fcf66a4 | 52 | **/\r |
ba0014b9 LG |
53 | STATIC\r |
54 | BOOLEAN\r | |
0fcf66a4 | 55 | StringToUint16 (\r |
68074260 RC |
56 | IN CONST CHAR16 *ValueStr,\r |
57 | OUT UINT16 *Value\r | |
58 | );\r | |
59 | \r | |
0fcf66a4 QS |
60 | /**\r |
61 | Get the name of the NIC.\r | |
62 | \r | |
63 | @param[in] ControllerHandle The network physical device handle.\r | |
64 | @param[in] NicNumber The network physical device number.\r | |
65 | @param[out] NicName Address where to store the NIC name.\r | |
66 | The memory area has to be at least\r | |
ba0014b9 | 67 | IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH\r |
6add86ab | 68 | double byte wide.\r |
0fcf66a4 QS |
69 | \r |
70 | @return EFI_SUCCESS The name of the NIC was returned.\r | |
71 | @return Others The creation of the child for the Managed\r | |
72 | Network Service failed or the opening of\r | |
73 | the Managed Network Protocol failed or\r | |
74 | the operational parameters for the\r | |
75 | Managed Network Protocol could not be\r | |
76 | read.\r | |
77 | **/\r | |
ba0014b9 LG |
78 | STATIC\r |
79 | EFI_STATUS\r | |
0fcf66a4 | 80 | GetNicName (\r |
68074260 | 81 | IN EFI_HANDLE ControllerHandle,\r |
a0f2af3a | 82 | IN UINTN NicNumber,\r |
68074260 RC |
83 | OUT CHAR16 *NicName\r |
84 | );\r | |
85 | \r | |
0fcf66a4 QS |
86 | /**\r |
87 | Create a child for the service identified by its service binding protocol GUID\r | |
88 | and get from the child the interface of the protocol identified by its GUID.\r | |
89 | \r | |
90 | @param[in] ControllerHandle Controller handle.\r | |
91 | @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the\r | |
92 | service to be created.\r | |
93 | @param[in] ProtocolGuid GUID of the protocol to be open.\r | |
94 | @param[out] ChildHandle Address where the handler of the\r | |
95 | created child is returned. NULL is\r | |
96 | returned in case of error.\r | |
97 | @param[out] Interface Address where a pointer to the\r | |
98 | protocol interface is returned in\r | |
99 | case of success.\r | |
100 | \r | |
101 | @return EFI_SUCCESS The child was created and the protocol opened.\r | |
102 | @return Others Either the creation of the child or the opening\r | |
103 | of the protocol failed.\r | |
104 | **/\r | |
ba0014b9 LG |
105 | STATIC\r |
106 | EFI_STATUS\r | |
0fcf66a4 | 107 | CreateServiceChildAndOpenProtocol (\r |
68074260 RC |
108 | IN EFI_HANDLE ControllerHandle,\r |
109 | IN EFI_GUID *ServiceBindingProtocolGuid,\r | |
110 | IN EFI_GUID *ProtocolGuid,\r | |
111 | OUT EFI_HANDLE *ChildHandle,\r | |
112 | OUT VOID **Interface\r | |
113 | );\r | |
114 | \r | |
0fcf66a4 QS |
115 | /**\r |
116 | Close the protocol identified by its GUID on the child handle of the service\r | |
117 | identified by its service binding protocol GUID, then destroy the child\r | |
118 | handle.\r | |
119 | \r | |
120 | @param[in] ControllerHandle Controller handle.\r | |
121 | @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the\r | |
122 | service to be destroyed.\r | |
123 | @param[in] ProtocolGuid GUID of the protocol to be closed.\r | |
124 | @param[in] ChildHandle Handle of the child to be destroyed.\r | |
125 | \r | |
126 | **/\r | |
ba0014b9 LG |
127 | STATIC\r |
128 | VOID\r | |
0fcf66a4 | 129 | CloseProtocolAndDestroyServiceChild (\r |
68074260 RC |
130 | IN EFI_HANDLE ControllerHandle,\r |
131 | IN EFI_GUID *ServiceBindingProtocolGuid,\r | |
132 | IN EFI_GUID *ProtocolGuid,\r | |
133 | IN EFI_HANDLE ChildHandle\r | |
134 | );\r | |
135 | \r | |
0fcf66a4 QS |
136 | /**\r |
137 | Worker function that gets the size in numbers of bytes of a file from a TFTP\r | |
138 | server before to download the file.\r | |
139 | \r | |
140 | @param[in] Mtftp4 MTFTP4 protocol interface\r | |
141 | @param[in] FilePath Path of the file, ASCII encoded\r | |
142 | @param[out] FileSize Address where to store the file size in number of\r | |
143 | bytes.\r | |
144 | \r | |
145 | @retval EFI_SUCCESS The size of the file was returned.\r | |
146 | @retval EFI_UNSUPPORTED The server does not support the "tsize" option.\r | |
147 | @retval Others Error when retrieving the information from the server\r | |
148 | (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)\r | |
149 | or error when parsing the response of the server.\r | |
150 | **/\r | |
ba0014b9 LG |
151 | STATIC\r |
152 | EFI_STATUS\r | |
0fcf66a4 | 153 | GetFileSize (\r |
68074260 RC |
154 | IN EFI_MTFTP4_PROTOCOL *Mtftp4,\r |
155 | IN CONST CHAR8 *FilePath,\r | |
156 | OUT UINTN *FileSize\r | |
157 | );\r | |
158 | \r | |
0fcf66a4 QS |
159 | /**\r |
160 | Worker function that download the data of a file from a TFTP server given\r | |
161 | the path of the file and its size.\r | |
162 | \r | |
163 | @param[in] Mtftp4 MTFTP4 protocol interface\r | |
164 | @param[in] FilePath Path of the file, Unicode encoded\r | |
165 | @param[in] AsciiFilePath Path of the file, ASCII encoded\r | |
166 | @param[in] FileSize Size of the file in number of bytes\r | |
2be45bfe | 167 | @param[in] BlockSize Value of the TFTP blksize option\r |
a7ab1c31 | 168 | @param[in] WindowSize Value of the TFTP window size option\r |
0fcf66a4 QS |
169 | \r |
170 | @retval EFI_SUCCESS The file was downloaded.\r | |
171 | @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r | |
172 | @retval Others The downloading of the file from the server failed\r | |
173 | (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).\r | |
174 | \r | |
175 | **/\r | |
ba0014b9 LG |
176 | STATIC\r |
177 | EFI_STATUS\r | |
0fcf66a4 | 178 | DownloadFile (\r |
68074260 RC |
179 | IN EFI_MTFTP4_PROTOCOL *Mtftp4,\r |
180 | IN CONST CHAR16 *FilePath,\r | |
181 | IN CONST CHAR8 *AsciiFilePath,\r | |
182 | IN UINTN FileSize,\r | |
2be45bfe | 183 | IN UINT16 BlockSize,\r |
b85c8fb4 | 184 | IN UINT16 WindowSize\r |
68074260 RC |
185 | );\r |
186 | \r | |
0fcf66a4 QS |
187 | /**\r |
188 | Update the progress of a file download\r | |
189 | This procedure is called each time a new TFTP packet is received.\r | |
190 | \r | |
191 | @param[in] This MTFTP4 protocol interface\r | |
192 | @param[in] Token Parameters for the download of the file\r | |
193 | @param[in] PacketLen Length of the packet\r | |
194 | @param[in] Packet Address of the packet\r | |
195 | \r | |
196 | @retval EFI_SUCCESS All packets are accepted.\r | |
197 | \r | |
198 | **/\r | |
ba0014b9 LG |
199 | STATIC\r |
200 | EFI_STATUS\r | |
7367e66f | 201 | EFIAPI\r |
0fcf66a4 | 202 | CheckPacket (\r |
68074260 RC |
203 | IN EFI_MTFTP4_PROTOCOL *This,\r |
204 | IN EFI_MTFTP4_TOKEN *Token,\r | |
205 | IN UINT16 PacketLen,\r | |
206 | IN EFI_MTFTP4_PACKET *Packet\r | |
207 | );\r | |
208 | \r | |
47d20b54 | 209 | EFI_MTFTP4_CONFIG_DATA DefaultMtftp4ConfigData = {\r |
68074260 | 210 | TRUE, // Use default setting\r |
47d20b54 MK |
211 | {\r |
212 | { 0, 0, 0, 0 }\r | |
213 | }, // StationIp - Not relevant as UseDefaultSetting=TRUE\r | |
214 | {\r | |
215 | { 0, 0, 0, 0 }\r | |
216 | }, // SubnetMask - Not relevant as UseDefaultSetting=TRUE\r | |
68074260 | 217 | 0, // LocalPort - Automatically assigned port number.\r |
47d20b54 MK |
218 | {\r |
219 | { 0, 0, 0, 0 }\r | |
220 | }, // GatewayIp - Not relevant as UseDefaultSetting=TRUE\r | |
221 | {\r | |
222 | { 0, 0, 0, 0 }\r | |
223 | }, // ServerIp - Not known yet\r | |
68074260 | 224 | 69, // InitialServerPort - Standard TFTP server port\r |
62ea70e3 | 225 | 6, // TryCount - The number of times to transmit request packets and wait for a response.\r |
68074260 RC |
226 | 4 // TimeoutValue - Retransmission timeout in seconds.\r |
227 | };\r | |
228 | \r | |
47d20b54 MK |
229 | STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r |
230 | { L"-i", TypeValue },\r | |
231 | { L"-l", TypeValue },\r | |
232 | { L"-r", TypeValue },\r | |
233 | { L"-c", TypeValue },\r | |
234 | { L"-t", TypeValue },\r | |
235 | { L"-s", TypeValue },\r | |
236 | { L"-w", TypeValue },\r | |
237 | { NULL, TypeMax }\r | |
238 | };\r | |
68074260 | 239 | \r |
2be45bfe FS |
240 | ///\r |
241 | /// The default block size (512) of tftp is defined in the RFC1350.\r | |
242 | ///\r | |
47d20b54 | 243 | #define MTFTP_DEFAULT_BLKSIZE 512\r |
2be45bfe FS |
244 | ///\r |
245 | /// The valid range of block size option is defined in the RFC2348.\r | |
246 | ///\r | |
47d20b54 MK |
247 | #define MTFTP_MIN_BLKSIZE 8\r |
248 | #define MTFTP_MAX_BLKSIZE 65464\r | |
5c6fdb5e JW |
249 | ///\r |
250 | /// The default windowsize (1) of tftp.\r | |
251 | ///\r | |
47d20b54 | 252 | #define MTFTP_DEFAULT_WINDOWSIZE 1\r |
5c6fdb5e JW |
253 | ///\r |
254 | /// The valid range of window size option.\r | |
255 | /// Note that: RFC 7440 does not mention max window size value, but for the\r | |
256 | /// stability reason, the value is limited to 64.\r | |
257 | ///\r | |
47d20b54 MK |
258 | #define MTFTP_MIN_WINDOWSIZE 1\r |
259 | #define MTFTP_MAX_WINDOWSIZE 64\r | |
2be45bfe | 260 | \r |
68074260 RC |
261 | /**\r |
262 | Function for 'tftp' command.\r | |
263 | \r | |
264 | @param[in] ImageHandle Handle to the Image (NULL if Internal).\r | |
265 | @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r | |
266 | \r | |
267 | @return SHELL_SUCCESS The 'tftp' command completed successfully.\r | |
268 | @return SHELL_ABORTED The Shell Library initialization failed.\r | |
269 | @return SHELL_INVALID_PARAMETER At least one of the command's arguments is\r | |
270 | not valid.\r | |
271 | @return SHELL_OUT_OF_RESOURCES A memory allocation failed.\r | |
272 | @return SHELL_NOT_FOUND Network Interface Card not found or server\r | |
273 | error or file error.\r | |
274 | \r | |
275 | **/\r | |
276 | SHELL_STATUS\r | |
09610023 | 277 | RunTftp (\r |
68074260 RC |
278 | IN EFI_HANDLE ImageHandle,\r |
279 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
280 | )\r | |
281 | {\r | |
282 | SHELL_STATUS ShellStatus;\r | |
283 | EFI_STATUS Status;\r | |
284 | LIST_ENTRY *CheckPackage;\r | |
285 | CHAR16 *ProblemParam;\r | |
286 | UINTN ParamCount;\r | |
287 | CONST CHAR16 *UserNicName;\r | |
288 | BOOLEAN NicFound;\r | |
289 | CONST CHAR16 *ValueStr;\r | |
290 | CONST CHAR16 *RemoteFilePath;\r | |
291 | CHAR8 *AsciiRemoteFilePath;\r | |
46213c8e | 292 | UINTN FilePathSize;\r |
68074260 | 293 | CONST CHAR16 *Walker;\r |
68074260 RC |
294 | EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData;\r |
295 | EFI_HANDLE *Handles;\r | |
296 | UINTN HandleCount;\r | |
297 | UINTN NicNumber;\r | |
6add86ab | 298 | CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH];\r |
68074260 RC |
299 | EFI_HANDLE ControllerHandle;\r |
300 | EFI_HANDLE Mtftp4ChildHandle;\r | |
301 | EFI_MTFTP4_PROTOCOL *Mtftp4;\r | |
302 | UINTN FileSize;\r | |
2be45bfe | 303 | UINT16 BlockSize;\r |
5c6fdb5e | 304 | UINT16 WindowSize;\r |
68074260 RC |
305 | \r |
306 | ShellStatus = SHELL_INVALID_PARAMETER;\r | |
307 | ProblemParam = NULL;\r | |
308 | NicFound = FALSE;\r | |
309 | AsciiRemoteFilePath = NULL;\r | |
310 | Handles = NULL;\r | |
6add86ab | 311 | FileSize = 0;\r |
2be45bfe | 312 | BlockSize = MTFTP_DEFAULT_BLKSIZE;\r |
5c6fdb5e | 313 | WindowSize = MTFTP_DEFAULT_WINDOWSIZE;\r |
68074260 RC |
314 | \r |
315 | //\r | |
316 | // Initialize the Shell library (we must be in non-auto-init...)\r | |
317 | //\r | |
318 | Status = ShellInitialize ();\r | |
319 | if (EFI_ERROR (Status)) {\r | |
320 | ASSERT_EFI_ERROR (Status);\r | |
321 | return SHELL_ABORTED;\r | |
322 | }\r | |
323 | \r | |
324 | //\r | |
325 | // Parse the command line.\r | |
326 | //\r | |
327 | Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);\r | |
328 | if (EFI_ERROR (Status)) {\r | |
329 | if ((Status == EFI_VOLUME_CORRUPTED) &&\r | |
47d20b54 MK |
330 | (ProblemParam != NULL))\r |
331 | {\r | |
68074260 | 332 | ShellPrintHiiEx (\r |
47d20b54 MK |
333 | -1,\r |
334 | -1,\r | |
335 | NULL,\r | |
336 | STRING_TOKEN (STR_GEN_PROBLEM),\r | |
337 | mTftpHiiHandle,\r | |
338 | L"tftp",\r | |
339 | ProblemParam\r | |
68074260 RC |
340 | );\r |
341 | FreePool (ProblemParam);\r | |
342 | } else {\r | |
343 | ASSERT (FALSE);\r | |
344 | }\r | |
47d20b54 | 345 | \r |
68074260 RC |
346 | goto Error;\r |
347 | }\r | |
348 | \r | |
349 | //\r | |
350 | // Check the number of parameters\r | |
351 | //\r | |
352 | ParamCount = ShellCommandLineGetCount (CheckPackage);\r | |
353 | if (ParamCount > 4) {\r | |
354 | ShellPrintHiiEx (\r | |
47d20b54 MK |
355 | -1,\r |
356 | -1,\r | |
357 | NULL,\r | |
358 | STRING_TOKEN (STR_GEN_TOO_MANY),\r | |
359 | mTftpHiiHandle,\r | |
360 | L"tftp"\r | |
68074260 RC |
361 | );\r |
362 | goto Error;\r | |
363 | }\r | |
47d20b54 | 364 | \r |
68074260 RC |
365 | if (ParamCount < 3) {\r |
366 | ShellPrintHiiEx (\r | |
47d20b54 MK |
367 | -1,\r |
368 | -1,\r | |
369 | NULL,\r | |
370 | STRING_TOKEN (STR_GEN_TOO_FEW),\r | |
371 | mTftpHiiHandle,\r | |
372 | L"tftp"\r | |
68074260 RC |
373 | );\r |
374 | goto Error;\r | |
375 | }\r | |
376 | \r | |
ba601bdd | 377 | CopyMem (&Mtftp4ConfigData, &DefaultMtftp4ConfigData, sizeof (EFI_MTFTP4_CONFIG_DATA));\r |
68074260 RC |
378 | \r |
379 | //\r | |
380 | // Check the host IPv4 address\r | |
381 | //\r | |
382 | ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);\r | |
47d20b54 | 383 | Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);\r |
68074260 RC |
384 | if (EFI_ERROR (Status)) {\r |
385 | ShellPrintHiiEx (\r | |
47d20b54 MK |
386 | -1,\r |
387 | -1,\r | |
388 | NULL,\r | |
389 | STRING_TOKEN (STR_GEN_PARAM_INV),\r | |
390 | mTftpHiiHandle,\r | |
391 | L"tftp",\r | |
392 | ValueStr\r | |
393 | );\r | |
68074260 RC |
394 | goto Error;\r |
395 | }\r | |
396 | \r | |
397 | RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);\r | |
47d20b54 MK |
398 | ASSERT (RemoteFilePath != NULL);\r |
399 | FilePathSize = StrLen (RemoteFilePath) + 1;\r | |
46213c8e | 400 | AsciiRemoteFilePath = AllocatePool (FilePathSize);\r |
68074260 RC |
401 | if (AsciiRemoteFilePath == NULL) {\r |
402 | ShellStatus = SHELL_OUT_OF_RESOURCES;\r | |
403 | goto Error;\r | |
404 | }\r | |
47d20b54 | 405 | \r |
46213c8e | 406 | UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);\r |
68074260 RC |
407 | \r |
408 | if (ParamCount == 4) {\r | |
b85c8fb4 | 409 | mLocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);\r |
68074260 RC |
410 | } else {\r |
411 | Walker = RemoteFilePath + StrLen (RemoteFilePath);\r | |
412 | while ((--Walker) >= RemoteFilePath) {\r | |
413 | if ((*Walker == L'\\') ||\r | |
47d20b54 MK |
414 | (*Walker == L'/'))\r |
415 | {\r | |
68074260 RC |
416 | break;\r |
417 | }\r | |
418 | }\r | |
47d20b54 | 419 | \r |
b85c8fb4 | 420 | mLocalFilePath = Walker + 1;\r |
68074260 RC |
421 | }\r |
422 | \r | |
423 | //\r | |
424 | // Get the name of the Network Interface Card to be used if any.\r | |
425 | //\r | |
426 | UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i");\r | |
427 | \r | |
428 | ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l");\r | |
429 | if (ValueStr != NULL) {\r | |
430 | if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) {\r | |
431 | goto Error;\r | |
432 | }\r | |
433 | }\r | |
434 | \r | |
435 | ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r");\r | |
436 | if (ValueStr != NULL) {\r | |
437 | if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) {\r | |
438 | goto Error;\r | |
439 | }\r | |
440 | }\r | |
441 | \r | |
442 | ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c");\r | |
443 | if (ValueStr != NULL) {\r | |
444 | if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) {\r | |
445 | goto Error;\r | |
446 | }\r | |
62ea70e3 JW |
447 | \r |
448 | if (Mtftp4ConfigData.TryCount == 0) {\r | |
449 | Mtftp4ConfigData.TryCount = 6;\r | |
450 | }\r | |
68074260 RC |
451 | }\r |
452 | \r | |
453 | ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");\r | |
454 | if (ValueStr != NULL) {\r | |
455 | if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) {\r | |
456 | goto Error;\r | |
457 | }\r | |
47d20b54 | 458 | \r |
68074260 RC |
459 | if (Mtftp4ConfigData.TimeoutValue == 0) {\r |
460 | ShellPrintHiiEx (\r | |
47d20b54 MK |
461 | -1,\r |
462 | -1,\r | |
463 | NULL,\r | |
464 | STRING_TOKEN (STR_GEN_PARAM_INV),\r | |
465 | mTftpHiiHandle,\r | |
466 | L"tftp",\r | |
467 | ValueStr\r | |
468 | );\r | |
68074260 RC |
469 | goto Error;\r |
470 | }\r | |
471 | }\r | |
472 | \r | |
2be45bfe FS |
473 | ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s");\r |
474 | if (ValueStr != NULL) {\r | |
475 | if (!StringToUint16 (ValueStr, &BlockSize)) {\r | |
476 | goto Error;\r | |
477 | }\r | |
47d20b54 MK |
478 | \r |
479 | if ((BlockSize < MTFTP_MIN_BLKSIZE) || (BlockSize > MTFTP_MAX_BLKSIZE)) {\r | |
2be45bfe | 480 | ShellPrintHiiEx (\r |
47d20b54 MK |
481 | -1,\r |
482 | -1,\r | |
483 | NULL,\r | |
484 | STRING_TOKEN (STR_GEN_PARAM_INV),\r | |
485 | mTftpHiiHandle,\r | |
486 | L"tftp",\r | |
487 | ValueStr\r | |
488 | );\r | |
2be45bfe FS |
489 | goto Error;\r |
490 | }\r | |
491 | }\r | |
492 | \r | |
5c6fdb5e JW |
493 | ValueStr = ShellCommandLineGetValue (CheckPackage, L"-w");\r |
494 | if (ValueStr != NULL) {\r | |
495 | if (!StringToUint16 (ValueStr, &WindowSize)) {\r | |
496 | goto Error;\r | |
497 | }\r | |
47d20b54 MK |
498 | \r |
499 | if ((WindowSize < MTFTP_MIN_WINDOWSIZE) || (WindowSize > MTFTP_MAX_WINDOWSIZE)) {\r | |
5c6fdb5e | 500 | ShellPrintHiiEx (\r |
47d20b54 MK |
501 | -1,\r |
502 | -1,\r | |
503 | NULL,\r | |
504 | STRING_TOKEN (STR_GEN_PARAM_INV),\r | |
505 | mTftpHiiHandle,\r | |
506 | L"tftp",\r | |
507 | ValueStr\r | |
508 | );\r | |
5c6fdb5e JW |
509 | goto Error;\r |
510 | }\r | |
511 | }\r | |
512 | \r | |
68074260 RC |
513 | //\r |
514 | // Locate all MTFTP4 Service Binding protocols\r | |
515 | //\r | |
516 | ShellStatus = SHELL_NOT_FOUND;\r | |
47d20b54 MK |
517 | Status = gBS->LocateHandleBuffer (\r |
518 | ByProtocol,\r | |
519 | &gEfiManagedNetworkServiceBindingProtocolGuid,\r | |
520 | NULL,\r | |
521 | &HandleCount,\r | |
522 | &Handles\r | |
523 | );\r | |
68074260 RC |
524 | if (EFI_ERROR (Status) || (HandleCount == 0)) {\r |
525 | ShellPrintHiiEx (\r | |
47d20b54 MK |
526 | -1,\r |
527 | -1,\r | |
528 | NULL,\r | |
529 | STRING_TOKEN (STR_TFTP_ERR_NO_NIC),\r | |
09610023 | 530 | mTftpHiiHandle\r |
47d20b54 | 531 | );\r |
68074260 RC |
532 | goto Error;\r |
533 | }\r | |
534 | \r | |
535 | for (NicNumber = 0;\r | |
536 | (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS);\r | |
47d20b54 MK |
537 | NicNumber++)\r |
538 | {\r | |
68074260 | 539 | ControllerHandle = Handles[NicNumber];\r |
68074260 RC |
540 | \r |
541 | Status = GetNicName (ControllerHandle, NicNumber, NicName);\r | |
542 | if (EFI_ERROR (Status)) {\r | |
543 | ShellPrintHiiEx (\r | |
47d20b54 MK |
544 | -1,\r |
545 | -1,\r | |
546 | NULL,\r | |
547 | STRING_TOKEN (STR_TFTP_ERR_NIC_NAME),\r | |
548 | mTftpHiiHandle,\r | |
549 | NicNumber,\r | |
550 | Status\r | |
551 | );\r | |
68074260 RC |
552 | continue;\r |
553 | }\r | |
554 | \r | |
555 | if (UserNicName != NULL) {\r | |
556 | if (StrCmp (NicName, UserNicName) != 0) {\r | |
557 | continue;\r | |
558 | }\r | |
47d20b54 | 559 | \r |
68074260 RC |
560 | NicFound = TRUE;\r |
561 | }\r | |
562 | \r | |
563 | Status = CreateServiceChildAndOpenProtocol (\r | |
564 | ControllerHandle,\r | |
565 | &gEfiMtftp4ServiceBindingProtocolGuid,\r | |
566 | &gEfiMtftp4ProtocolGuid,\r | |
567 | &Mtftp4ChildHandle,\r | |
47d20b54 | 568 | (VOID **)&Mtftp4\r |
68074260 RC |
569 | );\r |
570 | if (EFI_ERROR (Status)) {\r | |
571 | ShellPrintHiiEx (\r | |
47d20b54 MK |
572 | -1,\r |
573 | -1,\r | |
574 | NULL,\r | |
575 | STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),\r | |
576 | mTftpHiiHandle,\r | |
577 | NicName,\r | |
578 | Status\r | |
579 | );\r | |
68074260 RC |
580 | continue;\r |
581 | }\r | |
582 | \r | |
583 | Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData);\r | |
584 | if (EFI_ERROR (Status)) {\r | |
585 | ShellPrintHiiEx (\r | |
47d20b54 MK |
586 | -1,\r |
587 | -1,\r | |
588 | NULL,\r | |
589 | STRING_TOKEN (STR_TFTP_ERR_CONFIGURE),\r | |
590 | mTftpHiiHandle,\r | |
591 | NicName,\r | |
592 | Status\r | |
593 | );\r | |
68074260 RC |
594 | goto NextHandle;\r |
595 | }\r | |
596 | \r | |
597 | Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize);\r | |
598 | if (EFI_ERROR (Status)) {\r | |
599 | ShellPrintHiiEx (\r | |
47d20b54 MK |
600 | -1,\r |
601 | -1,\r | |
602 | NULL,\r | |
603 | STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE),\r | |
604 | mTftpHiiHandle,\r | |
605 | RemoteFilePath,\r | |
606 | NicName,\r | |
607 | Status\r | |
608 | );\r | |
68074260 RC |
609 | goto NextHandle;\r |
610 | }\r | |
611 | \r | |
b85c8fb4 | 612 | Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, WindowSize);\r |
68074260 RC |
613 | if (EFI_ERROR (Status)) {\r |
614 | ShellPrintHiiEx (\r | |
47d20b54 MK |
615 | -1,\r |
616 | -1,\r | |
617 | NULL,\r | |
618 | STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),\r | |
619 | mTftpHiiHandle,\r | |
620 | RemoteFilePath,\r | |
621 | NicName,\r | |
622 | Status\r | |
623 | );\r | |
68074260 RC |
624 | goto NextHandle;\r |
625 | }\r | |
626 | \r | |
83463154 VO |
627 | ShellStatus = SHELL_SUCCESS;\r |
628 | \r | |
47d20b54 | 629 | NextHandle:\r |
68074260 | 630 | \r |
68074260 RC |
631 | CloseProtocolAndDestroyServiceChild (\r |
632 | ControllerHandle,\r | |
633 | &gEfiMtftp4ServiceBindingProtocolGuid,\r | |
634 | &gEfiMtftp4ProtocolGuid,\r | |
635 | Mtftp4ChildHandle\r | |
636 | );\r | |
637 | }\r | |
638 | \r | |
a0f2af3a | 639 | if ((UserNicName != NULL) && (!NicFound)) {\r |
68074260 | 640 | ShellPrintHiiEx (\r |
47d20b54 MK |
641 | -1,\r |
642 | -1,\r | |
643 | NULL,\r | |
644 | STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),\r | |
645 | mTftpHiiHandle,\r | |
646 | UserNicName\r | |
647 | );\r | |
68074260 RC |
648 | }\r |
649 | \r | |
47d20b54 | 650 | Error:\r |
68074260 RC |
651 | \r |
652 | ShellCommandLineFreeVarList (CheckPackage);\r | |
653 | if (AsciiRemoteFilePath != NULL) {\r | |
654 | FreePool (AsciiRemoteFilePath);\r | |
655 | }\r | |
47d20b54 | 656 | \r |
68074260 RC |
657 | if (Handles != NULL) {\r |
658 | FreePool (Handles);\r | |
659 | }\r | |
660 | \r | |
47d20b54 | 661 | if ((ShellStatus != SHELL_SUCCESS) && (EFI_ERROR (Status))) {\r |
83463154 VO |
662 | ShellStatus = Status & ~MAX_BIT;\r |
663 | }\r | |
664 | \r | |
68074260 RC |
665 | return ShellStatus;\r |
666 | }\r | |
667 | \r | |
668 | /**\r | |
669 | Check and convert the UINT16 option values of the 'tftp' command\r | |
670 | \r | |
671 | @param[in] ValueStr Value as an Unicode encoded string\r | |
672 | @param[out] Value UINT16 value\r | |
673 | \r | |
674 | @return TRUE The value was returned.\r | |
f16bd394 | 675 | @return FALSE A parsing error occurred.\r |
68074260 RC |
676 | **/\r |
677 | STATIC\r | |
678 | BOOLEAN\r | |
679 | StringToUint16 (\r | |
680 | IN CONST CHAR16 *ValueStr,\r | |
681 | OUT UINT16 *Value\r | |
682 | )\r | |
683 | {\r | |
684 | UINTN Val;\r | |
685 | \r | |
686 | Val = ShellStrToUintn (ValueStr);\r | |
687 | if (Val > MAX_UINT16) {\r | |
688 | ShellPrintHiiEx (\r | |
47d20b54 MK |
689 | -1,\r |
690 | -1,\r | |
691 | NULL,\r | |
692 | STRING_TOKEN (STR_GEN_PARAM_INV),\r | |
693 | mTftpHiiHandle,\r | |
694 | L"tftp",\r | |
695 | ValueStr\r | |
696 | );\r | |
68074260 RC |
697 | return FALSE;\r |
698 | }\r | |
699 | \r | |
6add86ab | 700 | *Value = (UINT16)Val;\r |
68074260 RC |
701 | return TRUE;\r |
702 | }\r | |
703 | \r | |
704 | /**\r | |
705 | Get the name of the NIC.\r | |
706 | \r | |
707 | @param[in] ControllerHandle The network physical device handle.\r | |
708 | @param[in] NicNumber The network physical device number.\r | |
709 | @param[out] NicName Address where to store the NIC name.\r | |
710 | The memory area has to be at least\r | |
ba0014b9 | 711 | IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH\r |
6add86ab | 712 | double byte wide.\r |
68074260 RC |
713 | \r |
714 | @return EFI_SUCCESS The name of the NIC was returned.\r | |
715 | @return Others The creation of the child for the Managed\r | |
716 | Network Service failed or the opening of\r | |
717 | the Managed Network Protocol failed or\r | |
718 | the operational parameters for the\r | |
719 | Managed Network Protocol could not be\r | |
720 | read.\r | |
721 | **/\r | |
722 | STATIC\r | |
723 | EFI_STATUS\r | |
724 | GetNicName (\r | |
725 | IN EFI_HANDLE ControllerHandle,\r | |
726 | IN UINTN NicNumber,\r | |
727 | OUT CHAR16 *NicName\r | |
728 | )\r | |
729 | {\r | |
730 | EFI_STATUS Status;\r | |
731 | EFI_HANDLE MnpHandle;\r | |
732 | EFI_MANAGED_NETWORK_PROTOCOL *Mnp;\r | |
733 | EFI_SIMPLE_NETWORK_MODE SnpMode;\r | |
734 | \r | |
735 | Status = CreateServiceChildAndOpenProtocol (\r | |
736 | ControllerHandle,\r | |
737 | &gEfiManagedNetworkServiceBindingProtocolGuid,\r | |
738 | &gEfiManagedNetworkProtocolGuid,\r | |
739 | &MnpHandle,\r | |
47d20b54 | 740 | (VOID **)&Mnp\r |
68074260 RC |
741 | );\r |
742 | if (EFI_ERROR (Status)) {\r | |
743 | goto Error;\r | |
744 | }\r | |
745 | \r | |
746 | Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);\r | |
747 | if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r | |
748 | goto Error;\r | |
749 | }\r | |
750 | \r | |
751 | UnicodeSPrint (\r | |
752 | NicName,\r | |
6add86ab | 753 | IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,\r |
68074260 RC |
754 | SnpMode.IfType == NET_IFTYPE_ETHERNET ?\r |
755 | L"eth%d" :\r | |
47d20b54 | 756 | L"unk%d",\r |
68074260 RC |
757 | NicNumber\r |
758 | );\r | |
759 | \r | |
760 | Status = EFI_SUCCESS;\r | |
761 | \r | |
762 | Error:\r | |
763 | \r | |
764 | if (MnpHandle != NULL) {\r | |
765 | CloseProtocolAndDestroyServiceChild (\r | |
766 | ControllerHandle,\r | |
767 | &gEfiManagedNetworkServiceBindingProtocolGuid,\r | |
768 | &gEfiManagedNetworkProtocolGuid,\r | |
769 | MnpHandle\r | |
770 | );\r | |
771 | }\r | |
772 | \r | |
773 | return Status;\r | |
774 | }\r | |
775 | \r | |
776 | /**\r | |
777 | Create a child for the service identified by its service binding protocol GUID\r | |
778 | and get from the child the interface of the protocol identified by its GUID.\r | |
779 | \r | |
780 | @param[in] ControllerHandle Controller handle.\r | |
781 | @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the\r | |
782 | service to be created.\r | |
783 | @param[in] ProtocolGuid GUID of the protocol to be open.\r | |
784 | @param[out] ChildHandle Address where the handler of the\r | |
785 | created child is returned. NULL is\r | |
786 | returned in case of error.\r | |
787 | @param[out] Interface Address where a pointer to the\r | |
788 | protocol interface is returned in\r | |
789 | case of success.\r | |
790 | \r | |
791 | @return EFI_SUCCESS The child was created and the protocol opened.\r | |
792 | @return Others Either the creation of the child or the opening\r | |
793 | of the protocol failed.\r | |
794 | **/\r | |
795 | STATIC\r | |
796 | EFI_STATUS\r | |
797 | CreateServiceChildAndOpenProtocol (\r | |
798 | IN EFI_HANDLE ControllerHandle,\r | |
799 | IN EFI_GUID *ServiceBindingProtocolGuid,\r | |
800 | IN EFI_GUID *ProtocolGuid,\r | |
801 | OUT EFI_HANDLE *ChildHandle,\r | |
802 | OUT VOID **Interface\r | |
803 | )\r | |
804 | {\r | |
805 | EFI_STATUS Status;\r | |
806 | \r | |
807 | *ChildHandle = NULL;\r | |
47d20b54 MK |
808 | Status = NetLibCreateServiceChild (\r |
809 | ControllerHandle,\r | |
810 | gImageHandle,\r | |
811 | ServiceBindingProtocolGuid,\r | |
812 | ChildHandle\r | |
813 | );\r | |
68074260 RC |
814 | if (!EFI_ERROR (Status)) {\r |
815 | Status = gBS->OpenProtocol (\r | |
816 | *ChildHandle,\r | |
817 | ProtocolGuid,\r | |
818 | Interface,\r | |
819 | gImageHandle,\r | |
820 | ControllerHandle,\r | |
821 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r | |
822 | );\r | |
823 | if (EFI_ERROR (Status)) {\r | |
824 | NetLibDestroyServiceChild (\r | |
825 | ControllerHandle,\r | |
826 | gImageHandle,\r | |
827 | ServiceBindingProtocolGuid,\r | |
828 | *ChildHandle\r | |
829 | );\r | |
830 | *ChildHandle = NULL;\r | |
831 | }\r | |
832 | }\r | |
833 | \r | |
834 | return Status;\r | |
835 | }\r | |
836 | \r | |
837 | /**\r | |
838 | Close the protocol identified by its GUID on the child handle of the service\r | |
839 | identified by its service binding protocol GUID, then destroy the child\r | |
840 | handle.\r | |
841 | \r | |
842 | @param[in] ControllerHandle Controller handle.\r | |
843 | @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the\r | |
844 | service to be destroyed.\r | |
845 | @param[in] ProtocolGuid GUID of the protocol to be closed.\r | |
846 | @param[in] ChildHandle Handle of the child to be destroyed.\r | |
847 | \r | |
848 | **/\r | |
849 | STATIC\r | |
850 | VOID\r | |
851 | CloseProtocolAndDestroyServiceChild (\r | |
852 | IN EFI_HANDLE ControllerHandle,\r | |
853 | IN EFI_GUID *ServiceBindingProtocolGuid,\r | |
854 | IN EFI_GUID *ProtocolGuid,\r | |
855 | IN EFI_HANDLE ChildHandle\r | |
856 | )\r | |
857 | {\r | |
858 | gBS->CloseProtocol (\r | |
859 | ChildHandle,\r | |
860 | ProtocolGuid,\r | |
861 | gImageHandle,\r | |
862 | ControllerHandle\r | |
863 | );\r | |
864 | \r | |
865 | NetLibDestroyServiceChild (\r | |
866 | ControllerHandle,\r | |
867 | gImageHandle,\r | |
868 | ServiceBindingProtocolGuid,\r | |
869 | ChildHandle\r | |
870 | );\r | |
871 | }\r | |
872 | \r | |
873 | /**\r | |
874 | Worker function that gets the size in numbers of bytes of a file from a TFTP\r | |
875 | server before to download the file.\r | |
876 | \r | |
877 | @param[in] Mtftp4 MTFTP4 protocol interface\r | |
878 | @param[in] FilePath Path of the file, ASCII encoded\r | |
879 | @param[out] FileSize Address where to store the file size in number of\r | |
880 | bytes.\r | |
881 | \r | |
882 | @retval EFI_SUCCESS The size of the file was returned.\r | |
883 | @retval EFI_UNSUPPORTED The server does not support the "tsize" option.\r | |
884 | @retval Others Error when retrieving the information from the server\r | |
885 | (see EFI_MTFTP4_PROTOCOL.GetInfo() status codes)\r | |
886 | or error when parsing the response of the server.\r | |
887 | **/\r | |
888 | STATIC\r | |
889 | EFI_STATUS\r | |
890 | GetFileSize (\r | |
891 | IN EFI_MTFTP4_PROTOCOL *Mtftp4,\r | |
892 | IN CONST CHAR8 *FilePath,\r | |
893 | OUT UINTN *FileSize\r | |
894 | )\r | |
895 | {\r | |
896 | EFI_STATUS Status;\r | |
897 | EFI_MTFTP4_OPTION ReqOpt[1];\r | |
898 | EFI_MTFTP4_PACKET *Packet;\r | |
899 | UINT32 PktLen;\r | |
900 | EFI_MTFTP4_OPTION *TableOfOptions;\r | |
901 | EFI_MTFTP4_OPTION *Option;\r | |
902 | UINT32 OptCnt;\r | |
903 | UINT8 OptBuf[128];\r | |
904 | \r | |
47d20b54 MK |
905 | ReqOpt[0].OptionStr = (UINT8 *)"tsize";\r |
906 | OptBuf[0] = '0';\r | |
907 | OptBuf[1] = 0;\r | |
908 | ReqOpt[0].ValueStr = OptBuf;\r | |
68074260 RC |
909 | \r |
910 | Status = Mtftp4->GetInfo (\r | |
47d20b54 MK |
911 | Mtftp4,\r |
912 | NULL,\r | |
913 | (UINT8 *)FilePath,\r | |
914 | NULL,\r | |
915 | 1,\r | |
916 | ReqOpt,\r | |
917 | &PktLen,\r | |
918 | &Packet\r | |
919 | );\r | |
68074260 RC |
920 | \r |
921 | if (EFI_ERROR (Status)) {\r | |
922 | goto Error;\r | |
923 | }\r | |
924 | \r | |
925 | Status = Mtftp4->ParseOptions (\r | |
926 | Mtftp4,\r | |
927 | PktLen,\r | |
928 | Packet,\r | |
47d20b54 | 929 | (UINT32 *)&OptCnt,\r |
68074260 RC |
930 | &TableOfOptions\r |
931 | );\r | |
932 | if (EFI_ERROR (Status)) {\r | |
933 | goto Error;\r | |
934 | }\r | |
935 | \r | |
936 | Option = TableOfOptions;\r | |
937 | while (OptCnt != 0) {\r | |
938 | if (AsciiStrnCmp ((CHAR8 *)Option->OptionStr, "tsize", 5) == 0) {\r | |
939 | *FileSize = AsciiStrDecimalToUintn ((CHAR8 *)Option->ValueStr);\r | |
940 | break;\r | |
941 | }\r | |
47d20b54 | 942 | \r |
68074260 RC |
943 | OptCnt--;\r |
944 | Option++;\r | |
945 | }\r | |
47d20b54 | 946 | \r |
68074260 RC |
947 | FreePool (TableOfOptions);\r |
948 | \r | |
949 | if (OptCnt == 0) {\r | |
950 | Status = EFI_UNSUPPORTED;\r | |
951 | }\r | |
952 | \r | |
47d20b54 | 953 | Error:\r |
68074260 RC |
954 | \r |
955 | return Status;\r | |
956 | }\r | |
957 | \r | |
958 | /**\r | |
959 | Worker function that download the data of a file from a TFTP server given\r | |
960 | the path of the file and its size.\r | |
961 | \r | |
962 | @param[in] Mtftp4 MTFTP4 protocol interface\r | |
963 | @param[in] FilePath Path of the file, Unicode encoded\r | |
964 | @param[in] AsciiFilePath Path of the file, ASCII encoded\r | |
965 | @param[in] FileSize Size of the file in number of bytes\r | |
2be45bfe | 966 | @param[in] BlockSize Value of the TFTP blksize option\r |
a7ab1c31 | 967 | @param[in] WindowSize Value of the TFTP window size option\r |
68074260 RC |
968 | \r |
969 | @retval EFI_SUCCESS The file was downloaded.\r | |
970 | @retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r | |
971 | @retval Others The downloading of the file from the server failed\r | |
972 | (see EFI_MTFTP4_PROTOCOL.ReadFile() status codes).\r | |
973 | \r | |
974 | **/\r | |
975 | STATIC\r | |
976 | EFI_STATUS\r | |
977 | DownloadFile (\r | |
978 | IN EFI_MTFTP4_PROTOCOL *Mtftp4,\r | |
979 | IN CONST CHAR16 *FilePath,\r | |
980 | IN CONST CHAR8 *AsciiFilePath,\r | |
981 | IN UINTN FileSize,\r | |
2be45bfe | 982 | IN UINT16 BlockSize,\r |
b85c8fb4 | 983 | IN UINT16 WindowSize\r |
68074260 RC |
984 | )\r |
985 | {\r | |
47d20b54 MK |
986 | EFI_STATUS Status;\r |
987 | DOWNLOAD_CONTEXT *TftpContext;\r | |
988 | EFI_MTFTP4_TOKEN Mtftp4Token;\r | |
989 | UINT8 BlksizeBuf[10];\r | |
990 | UINT8 WindowsizeBuf[10];\r | |
68074260 | 991 | \r |
61d3f100 JW |
992 | ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));\r |
993 | \r | |
68074260 RC |
994 | TftpContext = AllocatePool (sizeof (DOWNLOAD_CONTEXT));\r |
995 | if (TftpContext == NULL) {\r | |
996 | Status = EFI_OUT_OF_RESOURCES;\r | |
997 | goto Error;\r | |
998 | }\r | |
47d20b54 MK |
999 | \r |
1000 | TftpContext->FileSize = FileSize;\r | |
68074260 RC |
1001 | TftpContext->DownloadedNbOfBytes = 0;\r |
1002 | TftpContext->LastReportedNbOfBytes = 0;\r | |
1003 | \r | |
47d20b54 | 1004 | Mtftp4Token.Filename = (UINT8 *)AsciiFilePath;\r |
68074260 | 1005 | Mtftp4Token.CheckPacket = CheckPacket;\r |
47d20b54 | 1006 | Mtftp4Token.Context = (VOID *)TftpContext;\r |
5c6fdb5e JW |
1007 | Mtftp4Token.OptionCount = 0;\r |
1008 | Mtftp4Token.OptionList = AllocatePool (sizeof (EFI_MTFTP4_OPTION) * 2);\r | |
1009 | if (Mtftp4Token.OptionList == NULL) {\r | |
1010 | Status = EFI_OUT_OF_RESOURCES;\r | |
1011 | goto Error;\r | |
1012 | }\r | |
1013 | \r | |
2be45bfe | 1014 | if (BlockSize != MTFTP_DEFAULT_BLKSIZE) {\r |
47d20b54 MK |
1015 | Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"blksize";\r |
1016 | AsciiSPrint ((CHAR8 *)BlksizeBuf, sizeof (BlksizeBuf), "%d", BlockSize);\r | |
1017 | Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = BlksizeBuf;\r | |
1018 | Mtftp4Token.OptionCount++;\r | |
5c6fdb5e | 1019 | }\r |
2be45bfe | 1020 | \r |
5c6fdb5e | 1021 | if (WindowSize != MTFTP_DEFAULT_WINDOWSIZE) {\r |
47d20b54 MK |
1022 | Mtftp4Token.OptionList[Mtftp4Token.OptionCount].OptionStr = (UINT8 *)"windowsize";\r |
1023 | AsciiSPrint ((CHAR8 *)WindowsizeBuf, sizeof (WindowsizeBuf), "%d", WindowSize);\r | |
1024 | Mtftp4Token.OptionList[Mtftp4Token.OptionCount].ValueStr = WindowsizeBuf;\r | |
1025 | Mtftp4Token.OptionCount++;\r | |
2be45bfe | 1026 | }\r |
68074260 RC |
1027 | \r |
1028 | ShellPrintHiiEx (\r | |
47d20b54 MK |
1029 | -1,\r |
1030 | -1,\r | |
1031 | NULL,\r | |
1032 | STRING_TOKEN (STR_TFTP_DOWNLOADING),\r | |
1033 | mTftpHiiHandle,\r | |
1034 | FilePath\r | |
68074260 RC |
1035 | );\r |
1036 | \r | |
b85c8fb4 AL |
1037 | //\r |
1038 | // OPEN FILE\r | |
1039 | //\r | |
1040 | if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {\r | |
1041 | ShellDeleteFileByName (mLocalFilePath);\r | |
1042 | }\r | |
1043 | \r | |
1044 | Status = ShellOpenFileByName (\r | |
47d20b54 MK |
1045 | mLocalFilePath,\r |
1046 | &mFileHandle,\r | |
1047 | EFI_FILE_MODE_CREATE |\r | |
1048 | EFI_FILE_MODE_WRITE |\r | |
1049 | EFI_FILE_MODE_READ,\r | |
1050 | 0\r | |
1051 | );\r | |
b85c8fb4 AL |
1052 | if (EFI_ERROR (Status)) {\r |
1053 | ShellPrintHiiEx (\r | |
47d20b54 MK |
1054 | -1,\r |
1055 | -1,\r | |
1056 | NULL,\r | |
1057 | STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),\r | |
1058 | mTftpHiiHandle,\r | |
1059 | L"tftp",\r | |
1060 | mLocalFilePath\r | |
1061 | );\r | |
b85c8fb4 AL |
1062 | goto Error;\r |
1063 | }\r | |
1064 | \r | |
68074260 RC |
1065 | Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);\r |
1066 | ShellPrintHiiEx (\r | |
47d20b54 MK |
1067 | -1,\r |
1068 | -1,\r | |
1069 | NULL,\r | |
1070 | STRING_TOKEN (STR_GEN_CRLF),\r | |
09610023 | 1071 | mTftpHiiHandle\r |
68074260 RC |
1072 | );\r |
1073 | \r | |
b85c8fb4 AL |
1074 | //\r |
1075 | // CLOSE FILE\r | |
1076 | //\r | |
1077 | ShellCloseFile (&mFileHandle);\r | |
68074260 | 1078 | \r |
47d20b54 | 1079 | Error:\r |
5c6fdb5e | 1080 | if (TftpContext != NULL) {\r |
68074260 RC |
1081 | FreePool (TftpContext);\r |
1082 | }\r | |
1083 | \r | |
5c6fdb5e JW |
1084 | if (Mtftp4Token.OptionList != NULL) {\r |
1085 | FreePool (Mtftp4Token.OptionList);\r | |
1086 | }\r | |
1087 | \r | |
b85c8fb4 | 1088 | return Status;\r |
68074260 RC |
1089 | }\r |
1090 | \r | |
1091 | /**\r | |
1092 | Update the progress of a file download\r | |
1093 | This procedure is called each time a new TFTP packet is received.\r | |
1094 | \r | |
1095 | @param[in] This MTFTP4 protocol interface\r | |
1096 | @param[in] Token Parameters for the download of the file\r | |
1097 | @param[in] PacketLen Length of the packet\r | |
1098 | @param[in] Packet Address of the packet\r | |
1099 | \r | |
1100 | @retval EFI_SUCCESS All packets are accepted.\r | |
1101 | \r | |
1102 | **/\r | |
1103 | STATIC\r | |
1104 | EFI_STATUS\r | |
7367e66f | 1105 | EFIAPI\r |
68074260 RC |
1106 | CheckPacket (\r |
1107 | IN EFI_MTFTP4_PROTOCOL *This,\r | |
1108 | IN EFI_MTFTP4_TOKEN *Token,\r | |
1109 | IN UINT16 PacketLen,\r | |
1110 | IN EFI_MTFTP4_PACKET *Packet\r | |
1111 | )\r | |
1112 | {\r | |
1113 | DOWNLOAD_CONTEXT *Context;\r | |
1114 | CHAR16 Progress[TFTP_PROGRESS_MESSAGE_SIZE];\r | |
6add86ab | 1115 | UINTN NbOfKb;\r |
68074260 | 1116 | UINTN Index;\r |
310b053a JC |
1117 | UINTN LastStep;\r |
1118 | UINTN Step;\r | |
b85c8fb4 | 1119 | UINTN DownloadLen;\r |
da6b8feb | 1120 | EFI_STATUS Status;\r |
68074260 RC |
1121 | \r |
1122 | if ((NTOHS (Packet->OpCode)) != EFI_MTFTP4_OPCODE_DATA) {\r | |
1123 | return EFI_SUCCESS;\r | |
1124 | }\r | |
1125 | \r | |
47d20b54 | 1126 | Context = (DOWNLOAD_CONTEXT *)Token->Context;\r |
68074260 RC |
1127 | \r |
1128 | //\r | |
1129 | // The data in the packet are prepended with two UINT16 :\r | |
1130 | // . OpCode = EFI_MTFTP4_OPCODE_DATA\r | |
1131 | // . Block = the number of this block of data\r | |
1132 | //\r | |
b85c8fb4 AL |
1133 | DownloadLen = (UINTN)PacketLen - sizeof (Packet->OpCode) - sizeof (Packet->Data.Block);\r |
1134 | \r | |
47d20b54 | 1135 | ShellSetFilePosition (mFileHandle, Context->DownloadedNbOfBytes);\r |
b85c8fb4 AL |
1136 | Status = ShellWriteFile (mFileHandle, &DownloadLen, Packet->Data.Data);\r |
1137 | if (EFI_ERROR (Status)) {\r | |
1138 | if (Context->DownloadedNbOfBytes > 0) {\r | |
1139 | ShellPrintHiiEx (\r | |
47d20b54 MK |
1140 | -1,\r |
1141 | -1,\r | |
1142 | NULL,\r | |
1143 | STRING_TOKEN (STR_GEN_CRLF),\r | |
b85c8fb4 | 1144 | mTftpHiiHandle\r |
47d20b54 | 1145 | );\r |
b85c8fb4 | 1146 | }\r |
47d20b54 | 1147 | \r |
b85c8fb4 | 1148 | ShellPrintHiiEx (\r |
47d20b54 MK |
1149 | -1,\r |
1150 | -1,\r | |
1151 | NULL,\r | |
1152 | STRING_TOKEN (STR_TFTP_ERR_WRITE),\r | |
1153 | mTftpHiiHandle,\r | |
1154 | mLocalFilePath,\r | |
1155 | Status\r | |
1156 | );\r | |
b85c8fb4 AL |
1157 | return Status;\r |
1158 | }\r | |
1159 | \r | |
1160 | if (Context->DownloadedNbOfBytes == 0) {\r | |
1161 | ShellPrintEx (-1, -1, L"%s 0 Kb", mTftpProgressFrame);\r | |
1162 | }\r | |
1163 | \r | |
1164 | Context->DownloadedNbOfBytes += DownloadLen;\r | |
47d20b54 | 1165 | NbOfKb = Context->DownloadedNbOfBytes / 1024;\r |
68074260 RC |
1166 | \r |
1167 | Progress[0] = L'\0';\r | |
47d20b54 MK |
1168 | LastStep = (Context->LastReportedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;\r |
1169 | Step = (Context->DownloadedNbOfBytes * TFTP_PROGRESS_SLIDER_STEPS) / Context->FileSize;\r | |
6add86ab | 1170 | \r |
68074260 RC |
1171 | if (Step <= LastStep) {\r |
1172 | return EFI_SUCCESS;\r | |
1173 | }\r | |
1174 | \r | |
1175 | ShellPrintEx (-1, -1, L"%s", mTftpProgressDelete);\r | |
1176 | \r | |
da6b8feb | 1177 | Status = StrCpyS (Progress, TFTP_PROGRESS_MESSAGE_SIZE, mTftpProgressFrame);\r |
47d20b54 | 1178 | if (EFI_ERROR (Status)) {\r |
da6b8feb QS |
1179 | return Status;\r |
1180 | }\r | |
47d20b54 | 1181 | \r |
68074260 RC |
1182 | for (Index = 1; Index < Step; Index++) {\r |
1183 | Progress[Index] = L'=';\r | |
1184 | }\r | |
47d20b54 | 1185 | \r |
68074260 RC |
1186 | Progress[Step] = L'>';\r |
1187 | \r | |
1188 | UnicodeSPrint (\r | |
1189 | Progress + (sizeof (mTftpProgressFrame) / sizeof (CHAR16)) - 1,\r | |
1190 | sizeof (Progress) - sizeof (mTftpProgressFrame),\r | |
1191 | L" %7d Kb",\r | |
1192 | NbOfKb\r | |
1193 | );\r | |
1194 | Context->LastReportedNbOfBytes = Context->DownloadedNbOfBytes;\r | |
1195 | \r | |
1196 | ShellPrintEx (-1, -1, L"%s", Progress);\r | |
1197 | \r | |
1198 | return EFI_SUCCESS;\r | |
1199 | }\r | |
09610023 RN |
1200 | \r |
1201 | /**\r | |
f16bd394 | 1202 | Retrieve HII package list from ImageHandle and publish to HII database.\r |
09610023 RN |
1203 | \r |
1204 | @param ImageHandle The image handle of the process.\r | |
1205 | \r | |
1206 | @return HII handle.\r | |
1207 | **/\r | |
c44501b3 | 1208 | EFI_HII_HANDLE\r |
09610023 | 1209 | InitializeHiiPackage (\r |
47d20b54 | 1210 | EFI_HANDLE ImageHandle\r |
09610023 RN |
1211 | )\r |
1212 | {\r | |
47d20b54 MK |
1213 | EFI_STATUS Status;\r |
1214 | EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r | |
1215 | EFI_HII_HANDLE HiiHandle;\r | |
09610023 RN |
1216 | \r |
1217 | //\r | |
1218 | // Retrieve HII package list from ImageHandle\r | |
1219 | //\r | |
1220 | Status = gBS->OpenProtocol (\r | |
1221 | ImageHandle,\r | |
1222 | &gEfiHiiPackageListProtocolGuid,\r | |
1223 | (VOID **)&PackageList,\r | |
1224 | ImageHandle,\r | |
1225 | NULL,\r | |
1226 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r | |
1227 | );\r | |
1228 | ASSERT_EFI_ERROR (Status);\r | |
1229 | if (EFI_ERROR (Status)) {\r | |
1230 | return NULL;\r | |
1231 | }\r | |
1232 | \r | |
1233 | //\r | |
1234 | // Publish HII package list to HII Database.\r | |
1235 | //\r | |
1236 | Status = gHiiDatabase->NewPackageList (\r | |
1237 | gHiiDatabase,\r | |
1238 | PackageList,\r | |
1239 | NULL,\r | |
1240 | &HiiHandle\r | |
1241 | );\r | |
1242 | ASSERT_EFI_ERROR (Status);\r | |
1243 | if (EFI_ERROR (Status)) {\r | |
1244 | return NULL;\r | |
1245 | }\r | |
47d20b54 | 1246 | \r |
09610023 RN |
1247 | return HiiHandle;\r |
1248 | }\r |