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