]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcMtftp.c
Update the copyright notice format
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcMtftp.c
CommitLineData
dc361cc5 1/** @file\r
f737cfb9 2 PxeBc MTFTP functions.\r
3 \r
e5eed7d3
HT
4Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
dc361cc5 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
dc361cc5 13**/\r
14\r
15#include "PxeBcImpl.h"\r
16\r
0adb8a3c 17CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {\r
dc361cc5 18 "blksize",\r
19 "timeout",\r
20 "tsize",\r
21 "multicast"\r
22};\r
23\r
24\r
25/**\r
26 This is a callback function when packets received/transmitted in Mtftp driver.\r
27\r
f737cfb9 28 A callback function that is provided by the caller to intercept \r
29 the EFI_MTFTP4_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the\r
30 EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept \r
31 EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to \r
32 EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().\r
33 \r
dc361cc5 34 @param This Pointer to Mtftp protocol instance\r
35 @param Token Pointer to Mtftp token\r
36 @param PacketLen Length of Mtftp packet\r
37 @param Packet Pointer to Mtftp packet\r
38\r
f737cfb9 39 @retval EFI_SUCCESS Operation sucess\r
40 @retval EFI_ABORTED Abort transfer process \r
dc361cc5 41\r
42**/\r
43EFI_STATUS\r
6d3ea23f 44EFIAPI\r
dc361cc5 45PxeBcCheckPacket (\r
46 IN EFI_MTFTP4_PROTOCOL *This,\r
47 IN EFI_MTFTP4_TOKEN *Token,\r
48 IN UINT16 PacketLen,\r
49 IN EFI_MTFTP4_PACKET *Packet\r
50 )\r
51{\r
52 PXEBC_PRIVATE_DATA *Private;\r
53 EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;\r
54 EFI_STATUS Status;\r
55\r
ea886bef 56 Private = (PXEBC_PRIVATE_DATA *) Token->Context;\r
dc361cc5 57 Callback = Private->PxeBcCallback;\r
58 Status = EFI_SUCCESS;\r
59\r
982a9eae 60 if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {\r
61 Private->Mode.TftpErrorReceived = TRUE;\r
62 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
63 AsciiStrnCpy (Private->Mode.TftpError.ErrorString, (CHAR8 *) Packet->Error.ErrorMessage, 127);\r
64 }\r
65\r
dc361cc5 66 if (Callback != NULL) {\r
67\r
68 Status = Callback->Callback (\r
69 Callback,\r
70 Private->Function,\r
71 TRUE,\r
72 PacketLen,\r
73 (EFI_PXE_BASE_CODE_PACKET *) Packet\r
74 );\r
75 if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
76\r
77 Status = EFI_ABORTED;\r
78 } else {\r
79\r
80 Status = EFI_SUCCESS;\r
81 }\r
82 }\r
83\r
84 return Status;\r
85}\r
86\r
87\r
88/**\r
89 This function is to get size of a file by Tftp.\r
f737cfb9 90 \r
dc361cc5 91 @param Private Pointer to PxeBc private data\r
92 @param Config Pointer to Mtftp configuration data\r
93 @param Filename Pointer to file name\r
94 @param BlockSize Pointer to block size\r
95 @param BufferSize Pointer to buffer size\r
96\r
f737cfb9 97 @retval EFI_SUCCESS Get the size of file success\r
98 @retval EFI_NOT_FOUND Parse the tftp ptions failed.\r
99 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
100 @retval Other Has not get the size of the file.\r
101 \r
dc361cc5 102**/\r
103EFI_STATUS\r
104PxeBcTftpGetFileSize (\r
105 IN PXEBC_PRIVATE_DATA *Private,\r
106 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
107 IN UINT8 *Filename,\r
108 IN UINTN *BlockSize,\r
109 IN OUT UINT64 *BufferSize\r
110 )\r
111{\r
112 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
113 EFI_MTFTP4_OPTION ReqOpt[2];\r
114 EFI_MTFTP4_PACKET *Packet;\r
115 EFI_MTFTP4_OPTION *Option;\r
116 UINT32 PktLen;\r
117 UINT8 OptBuf[128];\r
118 UINT32 OptCnt;\r
119 EFI_STATUS Status;\r
120\r
121 *BufferSize = 0;\r
122 Status = EFI_DEVICE_ERROR;\r
123 Mtftp4 = Private->Mtftp4;\r
124 Packet = NULL;\r
125 Option = NULL;\r
126 PktLen = 0;\r
127 OptCnt = 1;\r
128 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
129\r
130 Status = Mtftp4->Configure (Mtftp4, Config);\r
131 if (EFI_ERROR (Status)) {\r
132\r
133 return Status;\r
134 }\r
135\r
9c87ebc0 136 ReqOpt[0].OptionStr = (UINT8*)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
dc361cc5 137 UtoA10 (0, (CHAR8 *) OptBuf);\r
138 ReqOpt[0].ValueStr = OptBuf;\r
139\r
140 if (BlockSize != NULL) {\r
9c87ebc0 141 ReqOpt[1].OptionStr = (UINT8*)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
dc361cc5 142 ReqOpt[1].ValueStr = ReqOpt[0].ValueStr + AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1;\r
143 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[1].ValueStr);\r
144 OptCnt++;\r
145 }\r
146\r
147 Status = Mtftp4->GetInfo (\r
148 Mtftp4,\r
149 FALSE,\r
150 Filename,\r
151 NULL,\r
152 (UINT8) OptCnt,\r
153 ReqOpt,\r
154 &PktLen,\r
155 &Packet\r
156 );\r
157\r
158 if (EFI_ERROR (Status)) {\r
169a3461 159 if (Status == EFI_TFTP_ERROR) {\r
982a9eae 160 Private->Mode.TftpErrorReceived = TRUE;\r
161 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
f737cfb9 162 AsciiStrnCpy (\r
163 Private->Mode.TftpError.ErrorString, \r
164 (CHAR8 *) Packet->Error.ErrorMessage, \r
165 127\r
166 );\r
982a9eae 167 }\r
dc361cc5 168 goto ON_ERROR;\r
169 }\r
170\r
171 OptCnt = 0;\r
172\r
173 Status = Mtftp4->ParseOptions (\r
174 Mtftp4,\r
175 PktLen,\r
176 Packet,\r
177 (UINT32 *) &OptCnt,\r
178 &Option\r
179 );\r
180\r
181 if (EFI_ERROR (Status)) {\r
182\r
183 goto ON_ERROR;\r
184 }\r
185\r
186 Status = EFI_NOT_FOUND;\r
187\r
188 while (OptCnt != 0) {\r
189\r
190 if (AsciiStrnCmp ((CHAR8 *) Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {\r
191\r
192 *BufferSize = AtoU64 (Option[OptCnt - 1].ValueStr);\r
193 Status = EFI_SUCCESS;\r
194 }\r
195\r
196 OptCnt--;\r
197 }\r
198\r
766c7483 199 FreePool (Option);\r
dc361cc5 200\r
201ON_ERROR:\r
202\r
203 if (Packet != NULL) {\r
766c7483 204 FreePool (Packet);\r
dc361cc5 205 }\r
206\r
207 Mtftp4->Configure (Mtftp4, NULL);\r
208\r
209 return Status;\r
210}\r
211\r
212\r
213/**\r
214 This function is to get data of a file by Tftp.\r
215\r
216 @param Private Pointer to PxeBc private data\r
217 @param Config Pointer to Mtftp configuration data\r
218 @param Filename Pointer to file name\r
219 @param BlockSize Pointer to block size\r
220 @param BufferPtr Pointer to buffer\r
221 @param BufferSize Pointer to buffer size\r
222 @param DontUseBuffer Indicate whether with a receive buffer\r
223\r
f737cfb9 224 @retval EFI_SUCCESS Read the data success from the special file.\r
225 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
226 @retval other Read data from file failed.\r
227 \r
dc361cc5 228**/\r
229EFI_STATUS\r
230PxeBcTftpReadFile (\r
231 IN PXEBC_PRIVATE_DATA *Private,\r
232 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
233 IN UINT8 *Filename,\r
234 IN UINTN *BlockSize,\r
235 IN UINT8 *BufferPtr,\r
236 IN OUT UINT64 *BufferSize,\r
237 IN BOOLEAN DontUseBuffer\r
238 )\r
239{\r
240 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
241 EFI_MTFTP4_TOKEN Token;\r
242 EFI_MTFTP4_OPTION ReqOpt[1];\r
243 UINT32 OptCnt;\r
244 UINT8 OptBuf[128];\r
245 EFI_STATUS Status;\r
246\r
247 Status = EFI_DEVICE_ERROR;\r
248 Mtftp4 = Private->Mtftp4;\r
249 OptCnt = 0;\r
250 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
251\r
252 Status = Mtftp4->Configure (Mtftp4, Config);\r
253 if (EFI_ERROR (Status)) {\r
254\r
255 return Status;\r
256 }\r
257\r
258 if (BlockSize != NULL) {\r
259\r
8792362f 260 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
dc361cc5 261 ReqOpt[0].ValueStr = OptBuf;\r
262 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);\r
263 OptCnt++;\r
264 }\r
265\r
266 Token.Event = NULL;\r
267 Token.OverrideData = NULL;\r
268 Token.Filename = Filename;\r
269 Token.ModeStr = NULL;\r
270 Token.OptionCount = OptCnt;\r
271 Token.OptionList = ReqOpt;\r
ea886bef 272 Token.Context = Private;\r
dc361cc5 273\r
274 if (DontUseBuffer) {\r
275 Token.BufferSize = 0;\r
276 Token.Buffer = NULL;\r
277 } else {\r
278 Token.BufferSize = *BufferSize;\r
279 Token.Buffer = BufferPtr;\r
280 }\r
281\r
282 Token.CheckPacket = PxeBcCheckPacket;\r
283 Token.TimeoutCallback = NULL;\r
284 Token.PacketNeeded = NULL;\r
285\r
286 Status = Mtftp4->ReadFile (Mtftp4, &Token);\r
287\r
288 *BufferSize = Token.BufferSize;\r
289\r
290 Mtftp4->Configure (Mtftp4, NULL);\r
291\r
292 return Status;\r
293}\r
294\r
295\r
296/**\r
297 This function is put data of a file by Tftp.\r
298\r
299 @param Private Pointer to PxeBc private data\r
300 @param Config Pointer to Mtftp configuration data\r
301 @param Filename Pointer to file name\r
302 @param Overwrite Indicate whether with overwrite attribute\r
303 @param BlockSize Pointer to block size\r
304 @param BufferPtr Pointer to buffer\r
305 @param BufferSize Pointer to buffer size\r
306\r
f737cfb9 307 @retval EFI_SUCCESS Write the data success into the special file.\r
308 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
309 @retval other Write data into file failed.\r
310 \r
dc361cc5 311**/\r
312EFI_STATUS\r
313PxeBcTftpWriteFile (\r
314 IN PXEBC_PRIVATE_DATA *Private,\r
315 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
316 IN UINT8 *Filename,\r
317 IN BOOLEAN Overwrite,\r
318 IN UINTN *BlockSize,\r
319 IN UINT8 *BufferPtr,\r
320 IN OUT UINT64 *BufferSize\r
321 )\r
322{\r
323 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
324 EFI_MTFTP4_TOKEN Token;\r
325 EFI_MTFTP4_OPTION ReqOpt[1];\r
326 UINT32 OptCnt;\r
327 UINT8 OptBuf[128];\r
328 EFI_STATUS Status;\r
329\r
330 Status = EFI_DEVICE_ERROR;\r
331 Mtftp4 = Private->Mtftp4;\r
332 OptCnt = 0;\r
333 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
334\r
335 Status = Mtftp4->Configure (Mtftp4, Config);\r
336 if (EFI_ERROR (Status)) {\r
337\r
338 return Status;\r
339 }\r
340\r
341 if (BlockSize != NULL) {\r
342\r
8792362f 343 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
dc361cc5 344 ReqOpt[0].ValueStr = OptBuf;\r
345 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);\r
346 OptCnt++;\r
347 }\r
348\r
349 Token.Event = NULL;\r
350 Token.OverrideData = NULL;\r
351 Token.Filename = Filename;\r
352 Token.ModeStr = NULL;\r
353 Token.OptionCount = OptCnt;\r
354 Token.OptionList = ReqOpt;\r
355 Token.BufferSize = *BufferSize;\r
356 Token.Buffer = BufferPtr;\r
357 Token.CheckPacket = PxeBcCheckPacket;\r
358 Token.TimeoutCallback = NULL;\r
359 Token.PacketNeeded = NULL;\r
360\r
361 Status = Mtftp4->WriteFile (Mtftp4, &Token);\r
362 *BufferSize = Token.BufferSize;\r
363\r
364 Mtftp4->Configure (Mtftp4, NULL);\r
365\r
366 return Status;\r
367}\r
368\r
369\r
370/**\r
f737cfb9 371 This function is to get data(file) from a directory(may be a server) by Tftp.\r
372\r
373 @param Private Pointer to PxeBc private data.\r
374 @param Config Pointer to Mtftp configuration data.\r
375 @param Filename Pointer to file name.\r
376 @param BlockSize Pointer to block size.\r
377 @param BufferPtr Pointer to buffer.\r
378 @param BufferSize Pointer to buffer size.\r
379 @param DontUseBuffer Indicate whether with a receive buffer.\r
380\r
381 @retval EFI_SUCCES Get the data from the file included in directory success. \r
382 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.\r
383 @retval other Operation failed.\r
384 \r
dc361cc5 385**/\r
dc361cc5 386EFI_STATUS\r
387PxeBcTftpReadDirectory (\r
388 IN PXEBC_PRIVATE_DATA *Private,\r
389 IN EFI_MTFTP4_CONFIG_DATA *Config,\r
390 IN UINT8 *Filename,\r
391 IN UINTN *BlockSize,\r
392 IN UINT8 *BufferPtr,\r
393 IN OUT UINT64 *BufferSize,\r
394 IN BOOLEAN DontUseBuffer\r
395 )\r
396{\r
397 EFI_MTFTP4_PROTOCOL *Mtftp4;\r
398 EFI_MTFTP4_TOKEN Token;\r
399 EFI_MTFTP4_OPTION ReqOpt[1];\r
400 UINT32 OptCnt;\r
401 UINT8 OptBuf[128];\r
402 EFI_STATUS Status;\r
403\r
404 Status = EFI_DEVICE_ERROR;\r
405 Mtftp4 = Private->Mtftp4;\r
406 OptCnt = 0;\r
407 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;\r
408\r
409 Status = Mtftp4->Configure (Mtftp4, Config);\r
410 if (EFI_ERROR (Status)) {\r
411\r
412 return Status;\r
413 }\r
414\r
415 if (BlockSize != NULL) {\r
416\r
8792362f 417 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
dc361cc5 418 ReqOpt[0].ValueStr = OptBuf;\r
419 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);\r
420 OptCnt++;\r
421 }\r
422\r
423 Token.Event = NULL;\r
424 Token.OverrideData = NULL;\r
425 Token.Filename = Filename;\r
426 Token.ModeStr = NULL;\r
427 Token.OptionCount = OptCnt;\r
428 Token.OptionList = ReqOpt;\r
ea886bef 429 Token.Context = Private;\r
dc361cc5 430\r
431 if (DontUseBuffer) {\r
432 Token.BufferSize = 0;\r
433 Token.Buffer = NULL;\r
434 } else {\r
435 Token.BufferSize = *BufferSize;\r
436 Token.Buffer = BufferPtr;\r
437 }\r
438\r
439 Token.CheckPacket = PxeBcCheckPacket;\r
440 Token.TimeoutCallback = NULL;\r
441 Token.PacketNeeded = NULL;\r
442\r
443 Status = Mtftp4->ReadDirectory (Mtftp4, &Token);\r
444\r
445 *BufferSize = Token.BufferSize;\r
446\r
447 Mtftp4->Configure (Mtftp4, NULL);\r
448\r
449 return Status;\r
450}\r
451\r