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