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