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