]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcMtftp.c
1. Import UEFI PxeBc module in MdeModulePkg
[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 UINT8 *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 (Callback != NULL) {
64
65 Status = Callback->Callback (
66 Callback,
67 Private->Function,
68 TRUE,
69 PacketLen,
70 (EFI_PXE_BASE_CODE_PACKET *) Packet
71 );
72 if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
73
74 Status = EFI_ABORTED;
75 } else {
76
77 Status = EFI_SUCCESS;
78 }
79 }
80
81 return Status;
82 }
83
84
85 /**
86 This function is to get size of a file by Tftp.
87
88 @param Private Pointer to PxeBc private data
89 @param Config Pointer to Mtftp configuration data
90 @param Filename Pointer to file name
91 @param BlockSize Pointer to block size
92 @param BufferSize Pointer to buffer size
93
94 @return EFI_SUCCESS
95 @return EFI_NOT_FOUND
96 @return EFI_DEVICE_ERROR
97
98 **/
99 EFI_STATUS
100 PxeBcTftpGetFileSize (
101 IN PXEBC_PRIVATE_DATA *Private,
102 IN EFI_MTFTP4_CONFIG_DATA *Config,
103 IN UINT8 *Filename,
104 IN UINTN *BlockSize,
105 IN OUT UINT64 *BufferSize
106 )
107 {
108 EFI_MTFTP4_PROTOCOL *Mtftp4;
109 EFI_MTFTP4_OPTION ReqOpt[2];
110 EFI_MTFTP4_PACKET *Packet;
111 EFI_MTFTP4_OPTION *Option;
112 UINT32 PktLen;
113 UINT8 OptBuf[128];
114 UINT32 OptCnt;
115 EFI_STATUS Status;
116
117 *BufferSize = 0;
118 Status = EFI_DEVICE_ERROR;
119 Mtftp4 = Private->Mtftp4;
120 Packet = NULL;
121 Option = NULL;
122 PktLen = 0;
123 OptCnt = 1;
124 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
125
126 Status = Mtftp4->Configure (Mtftp4, Config);
127 if (EFI_ERROR (Status)) {
128
129 return Status;
130 }
131
132 ReqOpt[0].OptionStr = mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
133 UtoA10 (0, (CHAR8 *) OptBuf);
134 ReqOpt[0].ValueStr = OptBuf;
135
136 if (BlockSize != NULL) {
137 ReqOpt[1].OptionStr = mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
138 ReqOpt[1].ValueStr = ReqOpt[0].ValueStr + AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1;
139 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[1].ValueStr);
140 OptCnt++;
141 }
142
143 Status = Mtftp4->GetInfo (
144 Mtftp4,
145 FALSE,
146 Filename,
147 NULL,
148 (UINT8) OptCnt,
149 ReqOpt,
150 &PktLen,
151 &Packet
152 );
153
154 if (EFI_ERROR (Status)) {
155
156 goto ON_ERROR;
157 }
158
159 OptCnt = 0;
160
161 Status = Mtftp4->ParseOptions (
162 Mtftp4,
163 PktLen,
164 Packet,
165 (UINT32 *) &OptCnt,
166 &Option
167 );
168
169 if (EFI_ERROR (Status)) {
170
171 goto ON_ERROR;
172 }
173
174 Status = EFI_NOT_FOUND;
175
176 while (OptCnt != 0) {
177
178 if (AsciiStrnCmp ((CHAR8 *) Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
179
180 *BufferSize = AtoU64 (Option[OptCnt - 1].ValueStr);
181 Status = EFI_SUCCESS;
182 }
183
184 OptCnt--;
185 }
186
187 NetFreePool (Option);
188
189 ON_ERROR:
190
191 if (Packet != NULL) {
192 NetFreePool (Packet);
193 }
194
195 Mtftp4->Configure (Mtftp4, NULL);
196
197 return Status;
198 }
199
200
201 /**
202 This function is to get data of a file by Tftp.
203
204 @param Private Pointer to PxeBc private data
205 @param Config Pointer to Mtftp configuration data
206 @param Filename Pointer to file name
207 @param BlockSize Pointer to block size
208 @param BufferPtr Pointer to buffer
209 @param BufferSize Pointer to buffer size
210 @param DontUseBuffer Indicate whether with a receive buffer
211
212 @return EFI_SUCCESS
213 @return EFI_DEVICE_ERROR
214
215 **/
216 EFI_STATUS
217 PxeBcTftpReadFile (
218 IN PXEBC_PRIVATE_DATA *Private,
219 IN EFI_MTFTP4_CONFIG_DATA *Config,
220 IN UINT8 *Filename,
221 IN UINTN *BlockSize,
222 IN UINT8 *BufferPtr,
223 IN OUT UINT64 *BufferSize,
224 IN BOOLEAN DontUseBuffer
225 )
226 {
227 EFI_MTFTP4_PROTOCOL *Mtftp4;
228 EFI_MTFTP4_TOKEN Token;
229 EFI_MTFTP4_OPTION ReqOpt[1];
230 UINT32 OptCnt;
231 UINT8 OptBuf[128];
232 EFI_STATUS Status;
233
234 Status = EFI_DEVICE_ERROR;
235 Mtftp4 = Private->Mtftp4;
236 OptCnt = 0;
237 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
238
239 Status = Mtftp4->Configure (Mtftp4, Config);
240 if (EFI_ERROR (Status)) {
241
242 return Status;
243 }
244
245 if (BlockSize != NULL) {
246
247 ReqOpt[0].OptionStr = mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
248 ReqOpt[0].ValueStr = OptBuf;
249 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);
250 OptCnt++;
251 }
252
253 Token.Event = NULL;
254 Token.OverrideData = NULL;
255 Token.Filename = Filename;
256 Token.ModeStr = NULL;
257 Token.OptionCount = OptCnt;
258 Token.OptionList = ReqOpt;
259 TokenContext = Private;
260
261 if (DontUseBuffer) {
262 Token.BufferSize = 0;
263 Token.Buffer = NULL;
264 } else {
265 Token.BufferSize = *BufferSize;
266 Token.Buffer = BufferPtr;
267 }
268
269 Token.CheckPacket = PxeBcCheckPacket;
270 Token.TimeoutCallback = NULL;
271 Token.PacketNeeded = NULL;
272
273 Status = Mtftp4->ReadFile (Mtftp4, &Token);
274
275 *BufferSize = Token.BufferSize;
276
277 Mtftp4->Configure (Mtftp4, NULL);
278
279 return Status;
280 }
281
282
283 /**
284 This function is put data of a file by Tftp.
285
286 @param Private Pointer to PxeBc private data
287 @param Config Pointer to Mtftp configuration data
288 @param Filename Pointer to file name
289 @param Overwrite Indicate whether with overwrite attribute
290 @param BlockSize Pointer to block size
291 @param BufferPtr Pointer to buffer
292 @param BufferSize Pointer to buffer size
293
294 @return EFI_SUCCESS
295 @return EFI_DEVICE_ERROR
296
297 **/
298 EFI_STATUS
299 PxeBcTftpWriteFile (
300 IN PXEBC_PRIVATE_DATA *Private,
301 IN EFI_MTFTP4_CONFIG_DATA *Config,
302 IN UINT8 *Filename,
303 IN BOOLEAN Overwrite,
304 IN UINTN *BlockSize,
305 IN UINT8 *BufferPtr,
306 IN OUT UINT64 *BufferSize
307 )
308 {
309 EFI_MTFTP4_PROTOCOL *Mtftp4;
310 EFI_MTFTP4_TOKEN Token;
311 EFI_MTFTP4_OPTION ReqOpt[1];
312 UINT32 OptCnt;
313 UINT8 OptBuf[128];
314 EFI_STATUS Status;
315
316 Status = EFI_DEVICE_ERROR;
317 Mtftp4 = Private->Mtftp4;
318 OptCnt = 0;
319 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
320
321 Status = Mtftp4->Configure (Mtftp4, Config);
322 if (EFI_ERROR (Status)) {
323
324 return Status;
325 }
326
327 if (BlockSize != NULL) {
328
329 ReqOpt[0].OptionStr = mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
330 ReqOpt[0].ValueStr = OptBuf;
331 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);
332 OptCnt++;
333 }
334
335 Token.Event = NULL;
336 Token.OverrideData = NULL;
337 Token.Filename = Filename;
338 Token.ModeStr = NULL;
339 Token.OptionCount = OptCnt;
340 Token.OptionList = ReqOpt;
341 Token.BufferSize = *BufferSize;
342 Token.Buffer = BufferPtr;
343 Token.CheckPacket = PxeBcCheckPacket;
344 Token.TimeoutCallback = NULL;
345 Token.PacketNeeded = NULL;
346
347 Status = Mtftp4->WriteFile (Mtftp4, &Token);
348 *BufferSize = Token.BufferSize;
349
350 Mtftp4->Configure (Mtftp4, NULL);
351
352 return Status;
353 }
354
355
356 /**
357 This function is to get data of a directory by Tftp.
358
359 @param Private Pointer to PxeBc private data
360 @param Config Pointer to Mtftp configuration data
361 @param Filename Pointer to file name
362 @param BlockSize Pointer to block size
363 @param BufferPtr Pointer to buffer
364 @param BufferSize Pointer to buffer size
365 @param DontUseBuffer Indicate whether with a receive buffer
366
367 @return EFI_SUCCES
368 @return EFI_DEVICE_ERROR
369
370 **/
371 // GC_NOTO: EFI_SUCCESS - add return value to function comment
372 EFI_STATUS
373 PxeBcTftpReadDirectory (
374 IN PXEBC_PRIVATE_DATA *Private,
375 IN EFI_MTFTP4_CONFIG_DATA *Config,
376 IN UINT8 *Filename,
377 IN UINTN *BlockSize,
378 IN UINT8 *BufferPtr,
379 IN OUT UINT64 *BufferSize,
380 IN BOOLEAN DontUseBuffer
381 )
382 {
383 EFI_MTFTP4_PROTOCOL *Mtftp4;
384 EFI_MTFTP4_TOKEN Token;
385 EFI_MTFTP4_OPTION ReqOpt[1];
386 UINT32 OptCnt;
387 UINT8 OptBuf[128];
388 EFI_STATUS Status;
389
390 Status = EFI_DEVICE_ERROR;
391 Mtftp4 = Private->Mtftp4;
392 OptCnt = 0;
393 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
394
395 Status = Mtftp4->Configure (Mtftp4, Config);
396 if (EFI_ERROR (Status)) {
397
398 return Status;
399 }
400
401 if (BlockSize != NULL) {
402
403 ReqOpt[0].OptionStr = mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
404 ReqOpt[0].ValueStr = OptBuf;
405 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);
406 OptCnt++;
407 }
408
409 Token.Event = NULL;
410 Token.OverrideData = NULL;
411 Token.Filename = Filename;
412 Token.ModeStr = NULL;
413 Token.OptionCount = OptCnt;
414 Token.OptionList = ReqOpt;
415 TokenContext = Private;
416
417 if (DontUseBuffer) {
418 Token.BufferSize = 0;
419 Token.Buffer = NULL;
420 } else {
421 Token.BufferSize = *BufferSize;
422 Token.Buffer = BufferPtr;
423 }
424
425 Token.CheckPacket = PxeBcCheckPacket;
426 Token.TimeoutCallback = NULL;
427 Token.PacketNeeded = NULL;
428
429 Status = Mtftp4->ReadDirectory (Mtftp4, &Token);
430
431 *BufferSize = Token.BufferSize;
432
433 Mtftp4->Configure (Mtftp4, NULL);
434
435 return Status;
436 }
437