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