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