]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcMtftp.c
The pointer argument should be set to NULL if not used not FALSE.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcMtftp.c
... / ...
CommitLineData
1/** @file\r
2 PxeBc MTFTP functions.\r
3 \r
4Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
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
13**/\r
14\r
15#include "PxeBcImpl.h"\r
16\r
17CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {\r
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
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
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
39 @retval EFI_SUCCESS Operation sucess\r
40 @retval EFI_ABORTED Abort transfer process \r
41\r
42**/\r
43EFI_STATUS\r
44EFIAPI\r
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
56 Private = (PXEBC_PRIVATE_DATA *) Token->Context;\r
57 Callback = Private->PxeBcCallback;\r
58 Status = EFI_SUCCESS;\r
59\r
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
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
90 \r
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
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
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
136 ReqOpt[0].OptionStr = (UINT8*)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];\r
137 UtoA10 (0, (CHAR8 *) OptBuf);\r
138 ReqOpt[0].ValueStr = OptBuf;\r
139\r
140 if (BlockSize != NULL) {\r
141 ReqOpt[1].OptionStr = (UINT8*)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
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 NULL,\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
159 if (Status == EFI_TFTP_ERROR) {\r
160 Private->Mode.TftpErrorReceived = TRUE;\r
161 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;\r
162 AsciiStrnCpy (\r
163 Private->Mode.TftpError.ErrorString, \r
164 (CHAR8 *) Packet->Error.ErrorMessage, \r
165 127\r
166 );\r
167 }\r
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
199 FreePool (Option);\r
200\r
201ON_ERROR:\r
202\r
203 if (Packet != NULL) {\r
204 FreePool (Packet);\r
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
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
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
260 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
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
272 Token.Context = Private;\r
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
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
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
343 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
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
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
385**/\r
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
417 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];\r
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
429 Token.Context = Private;\r
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