]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/UefiPxeBcDxe/PxeBcMtftp.c
The pointer argument should be set to NULL if not used not FALSE.
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcMtftp.c
CommitLineData
a3bcde70
HT
1/** @file\r
2 Functions implementation related with Mtftp for UefiPxeBc Driver.\r
3\r
4e07e87f 4 Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
a3bcde70
HT
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "PxeBcImpl.h"\r
17\r
18CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {\r
19 "blksize",\r
20 "timeout",\r
21 "tsize",\r
22 "multicast"\r
23};\r
24\r
25\r
26/**\r
27 This is a callback function when packets are received or transmitted in Mtftp driver.\r
28\r
29 A callback function that is provided by the caller to intercept\r
30 the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP6_OPCODE_DATA8 packets processed in the\r
31 EFI_MTFTP6_PROTOCOL.ReadFile() function, and alternatively to intercept\r
32 EFI_MTFTP6_OPCODE_OACK or EFI_MTFTP6_OPCODE_ERROR packets during a call to\r
33 EFI_MTFTP6_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().\r
34\r
35 @param[in] This Pointer to EFI_MTFTP6_PROTOCOL.\r
36 @param[in] Token Pointer to EFI_MTFTP6_TOKEN.\r
37 @param[in] PacketLen Length of EFI_MTFTP6_PACKET.\r
38 @param[in] Packet Pointer to EFI_MTFTP6_PACKET to be checked.\r
39\r
40 @retval EFI_SUCCESS The current operation succeeded.\r
41 @retval EFI_ABORTED Abort the current transfer process.\r
42\r
43**/\r
44EFI_STATUS\r
45EFIAPI\r
46PxeBcMtftp6CheckPacket (\r
47 IN EFI_MTFTP6_PROTOCOL *This,\r
48 IN EFI_MTFTP6_TOKEN *Token,\r
49 IN UINT16 PacketLen,\r
50 IN EFI_MTFTP6_PACKET *Packet\r
51 )\r
52{\r
53 PXEBC_PRIVATE_DATA *Private;\r
54 EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;\r
55 EFI_STATUS Status;\r
56\r
57 Private = (PXEBC_PRIVATE_DATA *) Token->Context;\r
58 Callback = Private->PxeBcCallback;\r
59 Status = EFI_SUCCESS;\r
60\r
61 if (Packet->OpCode == EFI_MTFTP6_OPCODE_ERROR) {\r
62 //\r
63 // Store the tftp error message into mode data and set the received flag.\r
64 //\r
65 Private->Mode.TftpErrorReceived = TRUE;\r
66 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
67 AsciiStrnCpy (\r
68 Private->Mode.TftpError.ErrorString,\r
69 (CHAR8 *) Packet->Error.ErrorMessage,\r
70 PXE_MTFTP_ERROR_STRING_LENGTH\r
71 );\r
72 }\r
73\r
74 if (Callback != NULL) {\r
75 //\r
76 // Callback to user if has when received any tftp packet.\r
77 //\r
78 Status = Callback->Callback (\r
79 Callback,\r
80 Private->Function,\r
81 TRUE,\r
82 PacketLen,\r
83 (EFI_PXE_BASE_CODE_PACKET *) Packet\r
84 );\r
85 if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
86 //\r
87 // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.\r
88 //\r
89 Status = EFI_ABORTED;\r
90 } else {\r
91 //\r
92 // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.\r
93 //\r
94 Status = EFI_SUCCESS;\r
95 }\r
96 }\r
97\r
98 return Status;\r
99}\r
100\r
101\r
102/**\r
103 This function is to get the size of a file using Tftp.\r
104\r
105 @param[in] Private Pointer to PxeBc private data.\r
106 @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.\r
107 @param[in] Filename Pointer to boot file name.\r
108 @param[in] BlockSize Pointer to required block size.\r
109 @param[in, out] BufferSize Pointer to buffer size.\r
110\r
111 @retval EFI_SUCCESS Sucessfully obtained the size of file.\r
112 @retval EFI_NOT_FOUND Parse the tftp ptions failed.\r
113 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
114 @retval Others Has not obtained the size of the file.\r
115\r
116**/\r
117EFI_STATUS\r
118PxeBcMtftp6GetFileSize (\r
119 IN PXEBC_PRIVATE_DATA *Private,\r
120 IN EFI_MTFTP6_CONFIG_DATA *Config,\r
121 IN UINT8 *Filename,\r
122 IN UINTN *BlockSize,\r
123 IN OUT UINT64 *BufferSize\r
124 )\r
125{\r
126 EFI_MTFTP6_PROTOCOL *Mtftp6;\r
127 EFI_MTFTP6_OPTION ReqOpt[2];\r
128 EFI_MTFTP6_PACKET *Packet;\r
129 EFI_MTFTP6_OPTION *Option;\r
130 UINT32 PktLen;\r
131 UINT8 OptBuf[128];\r
132 UINT32 OptCnt;\r
133 EFI_STATUS Status;\r
134\r
135 *BufferSize = 0;\r
136 Status = EFI_DEVICE_ERROR;\r
137 Mtftp6 = Private->Mtftp6;\r
138 Packet = NULL;\r
139 Option = NULL;\r
140 PktLen = 0;\r
141 OptCnt = 1;\r
142 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
143\r
144 Status = Mtftp6->Configure (Mtftp6, Config);\r
145 if (EFI_ERROR (Status)) {\r
146 return Status;\r
147 }\r
148\r
149 //\r
150 // Build the required options for get info.\r
151 //\r
152 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
153 PxeBcUintnToAscDec (0, OptBuf);\r
154 ReqOpt[0].ValueStr = OptBuf;\r
155\r
156 if (BlockSize != NULL) {\r
157 ReqOpt[1].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
158 ReqOpt[1].ValueStr = (UINT8 *) (ReqOpt[0].ValueStr + AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1);\r
159 PxeBcUintnToAscDec (*BlockSize, ReqOpt[1].ValueStr);\r
160 OptCnt++;\r
161 }\r
162\r
163 Status = Mtftp6->GetInfo (\r
164 Mtftp6,\r
4e07e87f 165 NULL,\r
a3bcde70
HT
166 Filename,\r
167 NULL,\r
168 (UINT8) OptCnt,\r
169 ReqOpt,\r
170 &PktLen,\r
171 &Packet\r
172 );\r
173 if (EFI_ERROR (Status)) {\r
174 if (Status == EFI_TFTP_ERROR) {\r
175 //\r
176 // Store the tftp error message into mode data and set the received flag.\r
177 //\r
178 Private->Mode.TftpErrorReceived = TRUE;\r
179 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
180 AsciiStrnCpy (\r
181 Private->Mode.TftpError.ErrorString,\r
182 (CHAR8 *) Packet->Error.ErrorMessage,\r
183 PXE_MTFTP_ERROR_STRING_LENGTH\r
184 );\r
185 }\r
186 goto ON_ERROR;\r
187 }\r
188\r
189 //\r
190 // Parse the options in the reply packet.\r
191 //\r
192 OptCnt = 0;\r
193 Status = Mtftp6->ParseOptions (\r
194 Mtftp6,\r
195 PktLen,\r
196 Packet,\r
197 (UINT32 *) &OptCnt,\r
198 &Option\r
199 );\r
200 if (EFI_ERROR (Status)) {\r
201 goto ON_ERROR;\r
202 }\r
203\r
204 //\r
205 // Parse out the value of "tsize" option.\r
206 //\r
207 Status = EFI_NOT_FOUND;\r
208 while (OptCnt != 0) {\r
209 if (AsciiStrnCmp ((CHAR8 *) Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {\r
210 *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *) (Option[OptCnt - 1].ValueStr));\r
211 Status = EFI_SUCCESS;\r
212 }\r
213 OptCnt--;\r
214 }\r
215 FreePool (Option);\r
216\r
217ON_ERROR:\r
218 if (Packet != NULL) {\r
219 FreePool (Packet);\r
220 }\r
221 Mtftp6->Configure (Mtftp6, NULL);\r
222\r
223 return Status;\r
224}\r
225\r
226\r
227/**\r
228 This function is to get data of a file using Tftp.\r
229\r
230 @param[in] Private Pointer to PxeBc private data.\r
231 @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.\r
232 @param[in] Filename Pointer to boot file name.\r
233 @param[in] BlockSize Pointer to required block size.\r
234 @param[in] BufferPtr Pointer to buffer.\r
235 @param[in, out] BufferSize Pointer to buffer size.\r
236 @param[in] DontUseBuffer Indicates whether with a receive buffer.\r
237\r
238 @retval EFI_SUCCESS Successfully read the data from the special file.\r
239 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
240 @retval Others Read data from file failed.\r
241\r
242**/\r
243EFI_STATUS\r
244PxeBcMtftp6ReadFile (\r
245 IN PXEBC_PRIVATE_DATA *Private,\r
246 IN EFI_MTFTP6_CONFIG_DATA *Config,\r
247 IN UINT8 *Filename,\r
248 IN UINTN *BlockSize,\r
249 IN UINT8 *BufferPtr,\r
250 IN OUT UINT64 *BufferSize,\r
251 IN BOOLEAN DontUseBuffer\r
252 )\r
253{\r
254 EFI_MTFTP6_PROTOCOL *Mtftp6;\r
255 EFI_MTFTP6_TOKEN Token;\r
256 EFI_MTFTP6_OPTION ReqOpt[1];\r
257 UINT32 OptCnt;\r
258 UINT8 OptBuf[128];\r
259 EFI_STATUS Status;\r
260\r
261 Status = EFI_DEVICE_ERROR;\r
262 Mtftp6 = Private->Mtftp6;\r
263 OptCnt = 0;\r
264 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
265\r
266 Status = Mtftp6->Configure (Mtftp6, Config);\r
267 if (EFI_ERROR (Status)) {\r
268 return Status;\r
269 }\r
270\r
271 if (BlockSize != NULL) {\r
272 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
273 ReqOpt[0].ValueStr = OptBuf;\r
274 PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr);\r
275 OptCnt++;\r
276 }\r
277\r
278 Token.Event = NULL;\r
279 Token.OverrideData = NULL;\r
280 Token.Filename = Filename;\r
281 Token.ModeStr = NULL;\r
282 Token.OptionCount = OptCnt;\r
283 Token.OptionList = ReqOpt;\r
284 Token.Context = Private;\r
285\r
286 if (DontUseBuffer) {\r
287 Token.BufferSize = 0;\r
288 Token.Buffer = NULL;\r
289 } else {\r
290 Token.BufferSize = *BufferSize;\r
291 Token.Buffer = BufferPtr;\r
292 }\r
293\r
294 Token.CheckPacket = PxeBcMtftp6CheckPacket;\r
295 Token.TimeoutCallback = NULL;\r
296 Token.PacketNeeded = NULL;\r
297\r
298 Status = Mtftp6->ReadFile (Mtftp6, &Token);\r
299 //\r
300 // Get the real size of received buffer.\r
301 //\r
302 *BufferSize = Token.BufferSize;\r
303\r
304 Mtftp6->Configure (Mtftp6, NULL);\r
305\r
306 return Status;\r
307}\r
308\r
309\r
310/**\r
311 This function is used to write the data of a file using Tftp.\r
312\r
313 @param[in] Private Pointer to PxeBc private data.\r
314 @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.\r
315 @param[in] Filename Pointer to boot file name.\r
316 @param[in] Overwrite Indicate whether with overwrite attribute.\r
317 @param[in] BlockSize Pointer to required block size.\r
318 @param[in] BufferPtr Pointer to buffer.\r
319 @param[in, out] BufferSize Pointer to buffer size.\r
320\r
321 @retval EFI_SUCCESS Successfully wrote the data into a special file.\r
322 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
323 @retval other Write data into file failed.\r
324\r
325**/\r
326EFI_STATUS\r
327PxeBcMtftp6WriteFile (\r
328 IN PXEBC_PRIVATE_DATA *Private,\r
329 IN EFI_MTFTP6_CONFIG_DATA *Config,\r
330 IN UINT8 *Filename,\r
331 IN BOOLEAN Overwrite,\r
332 IN UINTN *BlockSize,\r
333 IN UINT8 *BufferPtr,\r
334 IN OUT UINT64 *BufferSize\r
335 )\r
336{\r
337 EFI_MTFTP6_PROTOCOL *Mtftp6;\r
338 EFI_MTFTP6_TOKEN Token;\r
339 EFI_MTFTP6_OPTION ReqOpt[1];\r
340 UINT32 OptCnt;\r
341 UINT8 OptBuf[128];\r
342 EFI_STATUS Status;\r
343\r
344 Status = EFI_DEVICE_ERROR;\r
345 Mtftp6 = Private->Mtftp6;\r
346 OptCnt = 0;\r
347 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
348\r
349 Status = Mtftp6->Configure (Mtftp6, Config);\r
350 if (EFI_ERROR (Status)) {\r
351 return Status;\r
352 }\r
353\r
354 if (BlockSize != NULL) {\r
355 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
356 ReqOpt[0].ValueStr = OptBuf;\r
357 PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr);\r
358 OptCnt++;\r
359 }\r
360\r
361 Token.Event = NULL;\r
362 Token.OverrideData = NULL;\r
363 Token.Filename = Filename;\r
364 Token.ModeStr = NULL;\r
365 Token.OptionCount = OptCnt;\r
366 Token.OptionList = ReqOpt;\r
367 Token.BufferSize = *BufferSize;\r
368 Token.Buffer = BufferPtr;\r
369 Token.CheckPacket = PxeBcMtftp6CheckPacket;\r
370 Token.TimeoutCallback = NULL;\r
371 Token.PacketNeeded = NULL;\r
372\r
373 Status = Mtftp6->WriteFile (Mtftp6, &Token);\r
374 //\r
375 // Get the real size of transmitted buffer.\r
376 //\r
377 *BufferSize = Token.BufferSize;\r
378\r
379 Mtftp6->Configure (Mtftp6, NULL);\r
380\r
381 return Status;\r
382}\r
383\r
384\r
385/**\r
386 This function is to read the data (file) from a directory using Tftp.\r
387\r
388 @param[in] Private Pointer to PxeBc private data.\r
389 @param[in] Config Pointer to EFI_MTFTP6_CONFIG_DATA.\r
390 @param[in] Filename Pointer to boot file name.\r
391 @param[in] BlockSize Pointer to required block size.\r
392 @param[in] BufferPtr Pointer to buffer.\r
393 @param[in, out] BufferSize Pointer to buffer size.\r
394 @param[in] DontUseBuffer Indicates whether to use a receive buffer.\r
395\r
396 @retval EFI_SUCCESS Successfully obtained the data from the file included in directory.\r
397 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
398 @retval Others Operation failed.\r
399\r
400**/\r
401EFI_STATUS\r
402PxeBcMtftp6ReadDirectory (\r
403 IN PXEBC_PRIVATE_DATA *Private,\r
404 IN EFI_MTFTP6_CONFIG_DATA *Config,\r
405 IN UINT8 *Filename,\r
406 IN UINTN *BlockSize,\r
407 IN UINT8 *BufferPtr,\r
408 IN OUT UINT64 *BufferSize,\r
409 IN BOOLEAN DontUseBuffer\r
410 )\r
411{\r
412 EFI_MTFTP6_PROTOCOL *Mtftp6;\r
413 EFI_MTFTP6_TOKEN Token;\r
414 EFI_MTFTP6_OPTION ReqOpt[1];\r
415 UINT32 OptCnt;\r
416 UINT8 OptBuf[128];\r
417 EFI_STATUS Status;\r
418\r
419 Status = EFI_DEVICE_ERROR;\r
420 Mtftp6 = Private->Mtftp6;\r
421 OptCnt = 0;\r
422 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
423\r
424 Status = Mtftp6->Configure (Mtftp6, Config);\r
425 if (EFI_ERROR (Status)) {\r
426 return Status;\r
427 }\r
428\r
429 if (BlockSize != NULL) {\r
430 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
431 ReqOpt[0].ValueStr = OptBuf;\r
432 PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr);\r
433 OptCnt++;\r
434 }\r
435\r
436 Token.Event = NULL;\r
437 Token.OverrideData = NULL;\r
438 Token.Filename = Filename;\r
439 Token.ModeStr = NULL;\r
440 Token.OptionCount = OptCnt;\r
441 Token.OptionList = ReqOpt;\r
442 Token.Context = Private;\r
443\r
444 if (DontUseBuffer) {\r
445 Token.BufferSize = 0;\r
446 Token.Buffer = NULL;\r
447 } else {\r
448 Token.BufferSize = *BufferSize;\r
449 Token.Buffer = BufferPtr;\r
450 }\r
451\r
452 Token.CheckPacket = PxeBcMtftp6CheckPacket;\r
453 Token.TimeoutCallback = NULL;\r
454 Token.PacketNeeded = NULL;\r
455\r
456 Status = Mtftp6->ReadDirectory (Mtftp6, &Token);\r
457 //\r
458 // Get the real size of received buffer.\r
459 //\r
460 *BufferSize = Token.BufferSize;\r
461\r
462 Mtftp6->Configure (Mtftp6, NULL);\r
463\r
464 return Status;\r
465}\r
466\r
467\r
468/**\r
469 This is a callback function when packets are received or transmitted in Mtftp driver.\r
470\r
471 A callback function that is provided by the caller to intercept\r
472 the EFI_MTFTP6_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the\r
473 EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept\r
474 EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to\r
475 EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().\r
476\r
477 @param[in] This Pointer to EFI_MTFTP4_PROTOCOL.\r
478 @param[in] Token Pointer to EFI_MTFTP4_TOKEN.\r
479 @param[in] PacketLen Length of EFI_MTFTP4_PACKET.\r
480 @param[in] Packet Pointer to EFI_MTFTP4_PACKET to be checked.\r
481\r
482 @retval EFI_SUCCESS The current operation succeeeded.\r
483 @retval EFI_ABORTED Abort the current transfer process.\r
484\r
485**/\r
486EFI_STATUS\r
487EFIAPI\r
488PxeBcMtftp4CheckPacket (\r
489 IN EFI_MTFTP4_PROTOCOL *This,\r
490 IN EFI_MTFTP4_TOKEN *Token,\r
491 IN UINT16 PacketLen,\r
492 IN EFI_MTFTP4_PACKET *Packet\r
493 )\r
494{\r
495 PXEBC_PRIVATE_DATA *Private;\r
496 EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;\r
497 EFI_STATUS Status;\r
498\r
499 Private = (PXEBC_PRIVATE_DATA *) Token->Context;\r
500 Callback = Private->PxeBcCallback;\r
501 Status = EFI_SUCCESS;\r
502\r
503 if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {\r
504 //\r
505 // Store the tftp error message into mode data and set the received flag.\r
506 //\r
507 Private->Mode.TftpErrorReceived = TRUE;\r
508 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
509 AsciiStrnCpy (\r
510 Private->Mode.TftpError.ErrorString,\r
511 (CHAR8 *) Packet->Error.ErrorMessage,\r
512 PXE_MTFTP_ERROR_STRING_LENGTH\r
513 );\r
514 }\r
515\r
516 if (Callback != NULL) {\r
517 //\r
518 // Callback to user if has when received any tftp packet.\r
519 //\r
520 Status = Callback->Callback (\r
521 Callback,\r
522 Private->Function,\r
523 TRUE,\r
524 PacketLen,\r
525 (EFI_PXE_BASE_CODE_PACKET *) Packet\r
526 );\r
527 if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
528 //\r
529 // User wants to abort current process if not EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.\r
530 //\r
531 Status = EFI_ABORTED;\r
532 } else {\r
533 //\r
534 // User wants to continue current process if EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE.\r
535 //\r
536 Status = EFI_SUCCESS;\r
537 }\r
538 }\r
539\r
540 return Status;\r
541}\r
542\r
543\r
544/**\r
545 This function is to get size of a file using Tftp.\r
546\r
547 @param[in] Private Pointer to PxeBc private data.\r
548 @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.\r
549 @param[in] Filename Pointer to boot file name.\r
550 @param[in] BlockSize Pointer to required block size.\r
551 @param[in, out] BufferSize Pointer to buffer size.\r
552\r
553 @retval EFI_SUCCESS Successfully obtained the size of file.\r
554 @retval EFI_NOT_FOUND Parse the tftp options failed.\r
555 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
556 @retval Others Did not obtain the size of the file.\r
557\r
558**/\r
559EFI_STATUS\r
560PxeBcMtftp4GetFileSize (\r
561 IN PXEBC_PRIVATE_DATA *Private,\r
562 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
563 IN UINT8 *Filename,\r
564 IN UINTN *BlockSize,\r
565 IN OUT UINT64 *BufferSize\r
566 )\r
567{\r
568 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
569 EFI_MTFTP4_OPTION ReqOpt[2];\r
570 EFI_MTFTP4_PACKET *Packet;\r
571 EFI_MTFTP4_OPTION *Option;\r
572 UINT32 PktLen;\r
573 UINT8 OptBuf[128];\r
574 UINT32 OptCnt;\r
575 EFI_STATUS Status;\r
576\r
577 *BufferSize = 0;\r
578 Status = EFI_DEVICE_ERROR;\r
579 Mtftp4 = Private->Mtftp4;\r
580 Packet = NULL;\r
581 Option = NULL;\r
582 PktLen = 0;\r
583 OptCnt = 1;\r
584 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
585\r
586 Status = Mtftp4->Configure (Mtftp4, Config);\r
587 if (EFI_ERROR (Status)) {\r
588 return Status;\r
589 }\r
590\r
591 //\r
592 // Build the required options for get info.\r
593 //\r
594 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
595 PxeBcUintnToAscDec (0, OptBuf);\r
596 ReqOpt[0].ValueStr = OptBuf;\r
597\r
598 if (BlockSize != NULL) {\r
599 ReqOpt[1].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
600 ReqOpt[1].ValueStr = (UINT8 *) (ReqOpt[0].ValueStr + AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1);\r
601 PxeBcUintnToAscDec (*BlockSize, ReqOpt[1].ValueStr);\r
602 OptCnt++;\r
603 }\r
604\r
605 Status = Mtftp4->GetInfo (\r
606 Mtftp4,\r
4e07e87f 607 NULL,\r
a3bcde70
HT
608 Filename,\r
609 NULL,\r
610 (UINT8) OptCnt,\r
611 ReqOpt,\r
612 &PktLen,\r
613 &Packet\r
614 );\r
615 if (EFI_ERROR (Status)) {\r
616 if (Status == EFI_TFTP_ERROR) {\r
617 //\r
618 // Store the tftp error message into mode data and set the received flag.\r
619 //\r
620 Private->Mode.TftpErrorReceived = TRUE;\r
621 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
622 AsciiStrnCpy (\r
623 Private->Mode.TftpError.ErrorString,\r
624 (CHAR8 *) Packet->Error.ErrorMessage,\r
625 PXE_MTFTP_ERROR_STRING_LENGTH\r
626 );\r
627 }\r
628 goto ON_ERROR;\r
629 }\r
630\r
631 //\r
632 // Parse the options in the reply packet.\r
633 //\r
634 OptCnt = 0;\r
635 Status = Mtftp4->ParseOptions (\r
636 Mtftp4,\r
637 PktLen,\r
638 Packet,\r
639 (UINT32 *) &OptCnt,\r
640 &Option\r
641 );\r
642 if (EFI_ERROR (Status)) {\r
643 goto ON_ERROR;\r
644 }\r
645\r
646 //\r
647 // Parse out the value of "tsize" option.\r
648 //\r
649 Status = EFI_NOT_FOUND;\r
650 while (OptCnt != 0) {\r
651 if (AsciiStrnCmp ((CHAR8 *) Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {\r
652 *BufferSize = AsciiStrDecimalToUint64 ((CHAR8 *) (Option[OptCnt - 1].ValueStr));\r
653 Status = EFI_SUCCESS;\r
654 }\r
655 OptCnt--;\r
656 }\r
657 FreePool (Option);\r
658\r
659ON_ERROR:\r
660 if (Packet != NULL) {\r
661 FreePool (Packet);\r
662 }\r
663 Mtftp4->Configure (Mtftp4, NULL);\r
664\r
665 return Status;\r
666}\r
667\r
668\r
669/**\r
670 This function is to read the data of a file using Tftp.\r
671\r
672 @param[in] Private Pointer to PxeBc private data.\r
673 @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.\r
674 @param[in] Filename Pointer to boot file name.\r
675 @param[in] BlockSize Pointer to required block size.\r
676 @param[in] BufferPtr Pointer to buffer.\r
677 @param[in, out] BufferSize Pointer to buffer size.\r
678 @param[in] DontUseBuffer Indicates whether to use a receive buffer.\r
679\r
680 @retval EFI_SUCCESS Successfully read the data from the special file.\r
681 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
682 @retval Others Read data from file failed.\r
683\r
684**/\r
685EFI_STATUS\r
686PxeBcMtftp4ReadFile (\r
687 IN PXEBC_PRIVATE_DATA *Private,\r
688 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
689 IN UINT8 *Filename,\r
690 IN UINTN *BlockSize,\r
691 IN UINT8 *BufferPtr,\r
692 IN OUT UINT64 *BufferSize,\r
693 IN BOOLEAN DontUseBuffer\r
694 )\r
695{\r
696 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
697 EFI_MTFTP4_TOKEN Token;\r
698 EFI_MTFTP4_OPTION ReqOpt[1];\r
699 UINT32 OptCnt;\r
700 UINT8 OptBuf[128];\r
701 EFI_STATUS Status;\r
702\r
703 Status = EFI_DEVICE_ERROR;\r
704 Mtftp4 = Private->Mtftp4;\r
705 OptCnt = 0;\r
706 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
707\r
708 Status = Mtftp4->Configure (Mtftp4, Config);\r
709 if (EFI_ERROR (Status)) {\r
710 return Status;\r
711 }\r
712\r
713 if (BlockSize != NULL) {\r
714 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
715 ReqOpt[0].ValueStr = OptBuf;\r
716 PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr);\r
717 OptCnt++;\r
718 }\r
719\r
720 Token.Event = NULL;\r
721 Token.OverrideData = NULL;\r
722 Token.Filename = Filename;\r
723 Token.ModeStr = NULL;\r
724 Token.OptionCount = OptCnt;\r
725 Token.OptionList = ReqOpt;\r
726 Token.Context = Private;\r
727\r
728 if (DontUseBuffer) {\r
729 Token.BufferSize = 0;\r
730 Token.Buffer = NULL;\r
731 } else {\r
732 Token.BufferSize = *BufferSize;\r
733 Token.Buffer = BufferPtr;\r
734 }\r
735\r
736 Token.CheckPacket = PxeBcMtftp4CheckPacket;\r
737 Token.TimeoutCallback = NULL;\r
738 Token.PacketNeeded = NULL;\r
739\r
740 Status = Mtftp4->ReadFile (Mtftp4, &Token);\r
741 //\r
742 // Get the real size of received buffer.\r
743 //\r
744 *BufferSize = Token.BufferSize;\r
745\r
746 Mtftp4->Configure (Mtftp4, NULL);\r
747\r
748 return Status;\r
749}\r
750\r
751\r
752/**\r
753 This function is to write the data of a file using Tftp.\r
754\r
755 @param[in] Private Pointer to PxeBc private data.\r
756 @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.\r
757 @param[in] Filename Pointer to boot file name.\r
758 @param[in] Overwrite Indicates whether to use the overwrite attribute.\r
759 @param[in] BlockSize Pointer to required block size.\r
760 @param[in] BufferPtr Pointer to buffer.\r
761 @param[in, out] BufferSize Pointer to buffer size.\r
762\r
763 @retval EFI_SUCCESS Successfully write the data into the special file.\r
764 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
765 @retval other Write data into file failed.\r
766\r
767**/\r
768EFI_STATUS\r
769PxeBcMtftp4WriteFile (\r
770 IN PXEBC_PRIVATE_DATA *Private,\r
771 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
772 IN UINT8 *Filename,\r
773 IN BOOLEAN Overwrite,\r
774 IN UINTN *BlockSize,\r
775 IN UINT8 *BufferPtr,\r
776 IN OUT UINT64 *BufferSize\r
777 )\r
778{\r
779 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
780 EFI_MTFTP4_TOKEN Token;\r
781 EFI_MTFTP4_OPTION ReqOpt[1];\r
782 UINT32 OptCnt;\r
783 UINT8 OptBuf[128];\r
784 EFI_STATUS Status;\r
785\r
786 Status = EFI_DEVICE_ERROR;\r
787 Mtftp4 = Private->Mtftp4;\r
788 OptCnt = 0;\r
789 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
790\r
791 Status = Mtftp4->Configure (Mtftp4, Config);\r
792 if (EFI_ERROR (Status)) {\r
793 return Status;\r
794 }\r
795\r
796 if (BlockSize != NULL) {\r
797 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
798 ReqOpt[0].ValueStr = OptBuf;\r
799 PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr);\r
800 OptCnt++;\r
801 }\r
802\r
803 Token.Event = NULL;\r
804 Token.OverrideData = NULL;\r
805 Token.Filename = Filename;\r
806 Token.ModeStr = NULL;\r
807 Token.OptionCount = OptCnt;\r
808 Token.OptionList = ReqOpt;\r
809 Token.BufferSize = *BufferSize;\r
810 Token.Buffer = BufferPtr;\r
811 Token.CheckPacket = PxeBcMtftp4CheckPacket;\r
812 Token.TimeoutCallback = NULL;\r
813 Token.PacketNeeded = NULL;\r
814\r
815 Status = Mtftp4->WriteFile (Mtftp4, &Token);\r
816 //\r
817 // Get the real size of transmitted buffer.\r
818 //\r
819 *BufferSize = Token.BufferSize;\r
820\r
821 Mtftp4->Configure (Mtftp4, NULL);\r
822\r
823 return Status;\r
824}\r
825\r
826\r
827/**\r
828 This function is to get data (file) from a directory using Tftp.\r
829\r
830 @param[in] Private Pointer to PxeBc private data.\r
831 @param[in] Config Pointer to EFI_MTFTP4_CONFIG_DATA.\r
832 @param[in] Filename Pointer to boot file name.\r
833 @param[in] BlockSize Pointer to required block size.\r
834 @param[in] BufferPtr Pointer to buffer.\r
835 @param[in, out] BufferSize Pointer to buffer size.\r
836 @param[in] DontUseBuffer Indicates whether to use a receive buffer.\r
837\r
838 @retval EFI_SUCCES Successfully obtained the data from the file included in the directory.\r
839 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
840 @retval Others Operation failed.\r
841\r
842**/\r
843EFI_STATUS\r
844PxeBcMtftp4ReadDirectory (\r
845 IN PXEBC_PRIVATE_DATA *Private,\r
846 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
847 IN UINT8 *Filename,\r
848 IN UINTN *BlockSize,\r
849 IN UINT8 *BufferPtr,\r
850 IN OUT UINT64 *BufferSize,\r
851 IN BOOLEAN DontUseBuffer\r
852 )\r
853{\r
854 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
855 EFI_MTFTP4_TOKEN Token;\r
856 EFI_MTFTP4_OPTION ReqOpt[1];\r
857 UINT32 OptCnt;\r
858 UINT8 OptBuf[128];\r
859 EFI_STATUS Status;\r
860\r
861 Status = EFI_DEVICE_ERROR;\r
862 Mtftp4 = Private->Mtftp4;\r
863 OptCnt = 0;\r
864 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
865\r
866 Status = Mtftp4->Configure (Mtftp4, Config);\r
867 if (EFI_ERROR (Status)) {\r
868 return Status;\r
869 }\r
870\r
871 if (BlockSize != NULL) {\r
872 ReqOpt[0].OptionStr = (UINT8 *) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
873 ReqOpt[0].ValueStr = OptBuf;\r
874 PxeBcUintnToAscDec (*BlockSize, ReqOpt[0].ValueStr);\r
875 OptCnt++;\r
876 }\r
877\r
878 Token.Event = NULL;\r
879 Token.OverrideData = NULL;\r
880 Token.Filename = Filename;\r
881 Token.ModeStr = NULL;\r
882 Token.OptionCount = OptCnt;\r
883 Token.OptionList = ReqOpt;\r
884 Token.Context = Private;\r
885\r
886 if (DontUseBuffer) {\r
887 Token.BufferSize = 0;\r
888 Token.Buffer = NULL;\r
889 } else {\r
890 Token.BufferSize = *BufferSize;\r
891 Token.Buffer = BufferPtr;\r
892 }\r
893\r
894 Token.CheckPacket = PxeBcMtftp4CheckPacket;\r
895 Token.TimeoutCallback = NULL;\r
896 Token.PacketNeeded = NULL;\r
897\r
898 Status = Mtftp4->ReadDirectory (Mtftp4, &Token);\r
899 //\r
900 // Get the real size of received buffer.\r
901 //\r
902 *BufferSize = Token.BufferSize;\r
903\r
904 Mtftp4->Configure (Mtftp4, NULL);\r
905\r
906 return Status;\r
907}\r
908\r
909\r
910/**\r
911 This function is wrapper to get the file size using TFTP.\r
912\r
913 @param[in] Private Pointer to PxeBc private data.\r
914 @param[in] Config Pointer to configure data.\r
915 @param[in] Filename Pointer to boot file name.\r
916 @param[in] BlockSize Pointer to required block size.\r
917 @param[in, out] BufferSize Pointer to buffer size.\r
918\r
919 @retval EFI_SUCCESS Successfully obtained the size of file.\r
920 @retval EFI_NOT_FOUND Parse the tftp options failed.\r
921 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
922 @retval Others Did not obtain the size of the file.\r
923\r
924**/\r
925EFI_STATUS\r
926PxeBcTftpGetFileSize (\r
927 IN PXEBC_PRIVATE_DATA *Private,\r
928 IN VOID *Config,\r
929 IN UINT8 *Filename,\r
930 IN UINTN *BlockSize,\r
931 IN OUT UINT64 *BufferSize\r
932 )\r
933{\r
934 if (Private->PxeBc.Mode->UsingIpv6) {\r
935 return PxeBcMtftp6GetFileSize (\r
936 Private,\r
937 (EFI_MTFTP6_CONFIG_DATA *) Config,\r
938 Filename,\r
939 BlockSize,\r
940 BufferSize\r
941 );\r
942 } else {\r
943 return PxeBcMtftp4GetFileSize (\r
944 Private,\r
945 (EFI_MTFTP4_CONFIG_DATA *) Config,\r
946 Filename,\r
947 BlockSize,\r
948 BufferSize\r
949 );\r
950 }\r
951}\r
952\r
953\r
954/**\r
955 This function is a wrapper to get file using TFTP.\r
956\r
957 @param[in] Private Pointer to PxeBc private data.\r
958 @param[in] Config Pointer to config data.\r
959 @param[in] Filename Pointer to boot file name.\r
960 @param[in] BlockSize Pointer to required block size.\r
961 @param[in] BufferPtr Pointer to buffer.\r
962 @param[in, out] BufferSize Pointer to buffer size.\r
963 @param[in] DontUseBuffer Indicates whether to use a receive buffer.\r
964\r
965 @retval EFI_SUCCESS Sucessfully read the data from the special file.\r
966 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
967 @retval Others Read data from file failed.\r
968\r
969**/\r
970EFI_STATUS\r
971PxeBcTftpReadFile (\r
972 IN PXEBC_PRIVATE_DATA *Private,\r
973 IN VOID *Config,\r
974 IN UINT8 *Filename,\r
975 IN UINTN *BlockSize,\r
976 IN UINT8 *BufferPtr,\r
977 IN OUT UINT64 *BufferSize,\r
978 IN BOOLEAN DontUseBuffer\r
979 )\r
980{\r
981 if (Private->PxeBc.Mode->UsingIpv6) {\r
982 return PxeBcMtftp6ReadFile (\r
983 Private,\r
984 (EFI_MTFTP6_CONFIG_DATA *) Config,\r
985 Filename,\r
986 BlockSize,\r
987 BufferPtr,\r
988 BufferSize,\r
989 DontUseBuffer\r
990 );\r
991 } else {\r
992 return PxeBcMtftp4ReadFile (\r
993 Private,\r
994 (EFI_MTFTP4_CONFIG_DATA *) Config,\r
995 Filename,\r
996 BlockSize,\r
997 BufferPtr,\r
998 BufferSize,\r
999 DontUseBuffer\r
1000 );\r
1001 }\r
1002}\r
1003\r
1004\r
1005/**\r
1006 This function is a wrapper to write file using TFTP.\r
1007\r
1008 @param[in] Private Pointer to PxeBc private data.\r
1009 @param[in] Config Pointer to config data.\r
1010 @param[in] Filename Pointer to boot file name.\r
1011 @param[in] Overwrite Indicate whether with overwrite attribute.\r
1012 @param[in] BlockSize Pointer to required block size.\r
1013 @param[in] BufferPtr Pointer to buffer.\r
1014 @param[in, out] BufferSize Pointer to buffer size.\r
1015\r
1016 @retval EFI_SUCCESS Successfully wrote the data into a special file.\r
1017 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
1018 @retval other Write data into file failed.\r
1019\r
1020**/\r
1021EFI_STATUS\r
1022PxeBcTftpWriteFile (\r
1023 IN PXEBC_PRIVATE_DATA *Private,\r
1024 IN VOID *Config,\r
1025 IN UINT8 *Filename,\r
1026 IN BOOLEAN Overwrite,\r
1027 IN UINTN *BlockSize,\r
1028 IN UINT8 *BufferPtr,\r
1029 IN OUT UINT64 *BufferSize\r
1030 )\r
1031{\r
1032 if (Private->PxeBc.Mode->UsingIpv6) {\r
1033 return PxeBcMtftp6WriteFile (\r
1034 Private,\r
1035 (EFI_MTFTP6_CONFIG_DATA *) Config,\r
1036 Filename,\r
1037 Overwrite,\r
1038 BlockSize,\r
1039 BufferPtr,\r
1040 BufferSize\r
1041 );\r
1042 } else {\r
1043 return PxeBcMtftp4WriteFile (\r
1044 Private,\r
1045 (EFI_MTFTP4_CONFIG_DATA *) Config,\r
1046 Filename,\r
1047 Overwrite,\r
1048 BlockSize,\r
1049 BufferPtr,\r
1050 BufferSize\r
1051 );\r
1052 }\r
1053}\r
1054\r
1055\r
1056/**\r
1057 This function is a wrapper to get the data (file) from a directory using TFTP.\r
1058\r
1059 @param[in] Private Pointer to PxeBc private data.\r
1060 @param[in] Config Pointer to config data.\r
1061 @param[in] Filename Pointer to boot file name.\r
1062 @param[in] BlockSize Pointer to required block size.\r
1063 @param[in] BufferPtr Pointer to buffer.\r
1064 @param[in, out] BufferSize Pointer to buffer size.\r
1065 @param[in] DontUseBuffer Indicatse whether to use a receive buffer.\r
1066\r
1067 @retval EFI_SUCCES Successfully obtained the data from the file included in the directory.\r
1068 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
1069 @retval Others Operation failed.\r
1070\r
1071**/\r
1072EFI_STATUS\r
1073PxeBcTftpReadDirectory (\r
1074 IN PXEBC_PRIVATE_DATA *Private,\r
1075 IN VOID *Config,\r
1076 IN UINT8 *Filename,\r
1077 IN UINTN *BlockSize,\r
1078 IN UINT8 *BufferPtr,\r
1079 IN OUT UINT64 *BufferSize,\r
1080 IN BOOLEAN DontUseBuffer\r
1081 )\r
1082{\r
1083 if (Private->PxeBc.Mode->UsingIpv6) {\r
1084 return PxeBcMtftp6ReadDirectory (\r
1085 Private,\r
1086 (EFI_MTFTP6_CONFIG_DATA *) Config,\r
1087 Filename,\r
1088 BlockSize,\r
1089 BufferPtr,\r
1090 BufferSize,\r
1091 DontUseBuffer\r
1092 );\r
1093 } else {\r
1094 return PxeBcMtftp4ReadDirectory (\r
1095 Private,\r
1096 (EFI_MTFTP4_CONFIG_DATA *) Config,\r
1097 Filename,\r
1098 BlockSize,\r
1099 BufferPtr,\r
1100 BufferSize,\r
1101 DontUseBuffer\r
1102 );\r
1103 }\r
1104}\r
1105\r