]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Bds/BootOptionSupport.c
Add check to make code more safely.
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootOptionSupport.c
CommitLineData
ea46ebbe 1/** @file\r
2*\r
55a9f75d 3* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
ea46ebbe 4*\r
5* This program and the accompanying materials\r
6* are licensed and made available under the terms and conditions of the BSD License\r
7* which accompanies this distribution. The full text of the license may be found at\r
8* http://opensource.org/licenses/bsd-license.php\r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12*\r
13**/\r
14\r
15#include "BdsInternal.h"\r
16\r
17#include <Library/NetLib.h>\r
18\r
19#include <Protocol/BlockIo.h>\r
20#include <Protocol/DevicePathToText.h>\r
21#include <Protocol/PxeBaseCode.h>\r
22#include <Protocol/SimpleFileSystem.h>\r
23#include <Protocol/SimpleNetwork.h>\r
24\r
25#include <Guid/FileSystemInfo.h>\r
26\r
27#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))\r
28\r
29EFI_STATUS\r
30BdsLoadOptionFileSystemList (\r
31 IN OUT LIST_ENTRY* BdsLoadOptionList\r
32 );\r
33\r
34EFI_STATUS\r
35BdsLoadOptionFileSystemCreateDevicePath (\r
22a262c8 36 IN CHAR16* FileName,\r
ecc62d13 37 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 38 OUT BOOLEAN *RequestBootType\r
ea46ebbe 39 );\r
40\r
41EFI_STATUS\r
42BdsLoadOptionFileSystemUpdateDevicePath (\r
22a262c8 43 IN EFI_DEVICE_PATH *OldDevicePath,\r
44 IN CHAR16* FileName,\r
45 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 46 OUT BOOLEAN *RequestBootType\r
ea46ebbe 47 );\r
48\r
49BOOLEAN\r
50BdsLoadOptionFileSystemIsSupported (\r
22a262c8 51 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 52 );\r
53\r
54EFI_STATUS\r
55BdsLoadOptionMemMapList (\r
56 IN OUT LIST_ENTRY* BdsLoadOptionList\r
57 );\r
58\r
59EFI_STATUS\r
60BdsLoadOptionMemMapCreateDevicePath (\r
22a262c8 61 IN CHAR16* FileName,\r
ecc62d13 62 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 63 OUT BOOLEAN *RequestBootType\r
ea46ebbe 64 );\r
65\r
66EFI_STATUS\r
67BdsLoadOptionMemMapUpdateDevicePath (\r
22a262c8 68 IN EFI_DEVICE_PATH *OldDevicePath,\r
69 IN CHAR16* FileName,\r
70 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 71 OUT BOOLEAN *RequestBootType\r
ea46ebbe 72 );\r
73\r
74BOOLEAN\r
75BdsLoadOptionMemMapIsSupported (\r
22a262c8 76 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 77 );\r
78\r
79EFI_STATUS\r
80BdsLoadOptionPxeList (\r
81 IN OUT LIST_ENTRY* BdsLoadOptionList\r
82 );\r
83\r
84EFI_STATUS\r
85BdsLoadOptionPxeCreateDevicePath (\r
22a262c8 86 IN CHAR16* FileName,\r
ecc62d13 87 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 88 OUT BOOLEAN *RequestBootType\r
ea46ebbe 89 );\r
90\r
91EFI_STATUS\r
92BdsLoadOptionPxeUpdateDevicePath (\r
22a262c8 93 IN EFI_DEVICE_PATH *OldDevicePath,\r
94 IN CHAR16* FileName,\r
95 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 96 OUT BOOLEAN *RequestBootType\r
ea46ebbe 97 );\r
98\r
99BOOLEAN\r
100BdsLoadOptionPxeIsSupported (\r
22a262c8 101 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 102 );\r
103\r
104EFI_STATUS\r
105BdsLoadOptionTftpList (\r
106 IN OUT LIST_ENTRY* BdsLoadOptionList\r
107 );\r
108\r
109EFI_STATUS\r
110BdsLoadOptionTftpCreateDevicePath (\r
22a262c8 111 IN CHAR16* FileName,\r
ecc62d13 112 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 113 OUT BOOLEAN *RequestBootType\r
ea46ebbe 114 );\r
115\r
116EFI_STATUS\r
117BdsLoadOptionTftpUpdateDevicePath (\r
22a262c8 118 IN EFI_DEVICE_PATH *OldDevicePath,\r
119 IN CHAR16* FileName,\r
120 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 121 OUT BOOLEAN *RequestBootType\r
ea46ebbe 122 );\r
123\r
124BOOLEAN\r
125BdsLoadOptionTftpIsSupported (\r
22a262c8 126 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 127 );\r
128\r
129BDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList[] = {\r
2ccfb71e 130 {\r
131 BDS_DEVICE_FILESYSTEM,\r
132 BdsLoadOptionFileSystemList,\r
133 BdsLoadOptionFileSystemIsSupported,\r
134 BdsLoadOptionFileSystemCreateDevicePath,\r
135 BdsLoadOptionFileSystemUpdateDevicePath\r
136 },\r
137 {\r
138 BDS_DEVICE_MEMMAP,\r
139 BdsLoadOptionMemMapList,\r
140 BdsLoadOptionMemMapIsSupported,\r
141 BdsLoadOptionMemMapCreateDevicePath,\r
142 BdsLoadOptionMemMapUpdateDevicePath\r
143 },\r
144 {\r
145 BDS_DEVICE_PXE,\r
146 BdsLoadOptionPxeList,\r
147 BdsLoadOptionPxeIsSupported,\r
148 BdsLoadOptionPxeCreateDevicePath,\r
149 BdsLoadOptionPxeUpdateDevicePath\r
150 },\r
151 {\r
152 BDS_DEVICE_TFTP,\r
153 BdsLoadOptionTftpList,\r
154 BdsLoadOptionTftpIsSupported,\r
155 BdsLoadOptionTftpCreateDevicePath,\r
156 BdsLoadOptionTftpUpdateDevicePath\r
157 }\r
ea46ebbe 158};\r
159\r
160EFI_STATUS\r
161BootDeviceListSupportedInit (\r
162 IN OUT LIST_ENTRY *SupportedDeviceList\r
163 )\r
164{\r
165 UINTN Index;\r
166\r
167 // Initialize list of supported devices\r
168 InitializeListHead (SupportedDeviceList);\r
169\r
170 for (Index = 0; Index < BDS_DEVICE_MAX; Index++) {\r
2ccfb71e 171 BdsLoadOptionSupportList[Index].ListDevices (SupportedDeviceList);\r
ea46ebbe 172 }\r
173\r
174 return EFI_SUCCESS;\r
175}\r
176\r
177EFI_STATUS\r
178BootDeviceListSupportedFree (\r
656416bc 179 IN LIST_ENTRY *SupportedDeviceList,\r
180 IN BDS_SUPPORTED_DEVICE *Except\r
ea46ebbe 181 )\r
182{\r
183 LIST_ENTRY *Entry;\r
184 BDS_SUPPORTED_DEVICE* SupportedDevice;\r
185\r
186 Entry = GetFirstNode (SupportedDeviceList);\r
187 while (Entry != SupportedDeviceList) {\r
188 SupportedDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);\r
189 Entry = RemoveEntryList (Entry);\r
656416bc 190 if (SupportedDevice != Except) {\r
2ccfb71e 191 FreePool (SupportedDevice);\r
656416bc 192 }\r
ea46ebbe 193 }\r
194\r
195 return EFI_SUCCESS;\r
196}\r
197\r
198EFI_STATUS\r
199BootDeviceGetDeviceSupport (\r
22a262c8 200 IN EFI_DEVICE_PATH *DevicePath,\r
201 OUT BDS_LOAD_OPTION_SUPPORT **DeviceSupport\r
ea46ebbe 202 )\r
203{\r
204 UINTN Index;\r
205\r
206 // Find which supported device is the most appropriate\r
207 for (Index = 0; Index < BDS_DEVICE_MAX; Index++) {\r
22a262c8 208 if (BdsLoadOptionSupportList[Index].IsSupported (DevicePath)) {\r
ea46ebbe 209 *DeviceSupport = &BdsLoadOptionSupportList[Index];\r
210 return EFI_SUCCESS;\r
211 }\r
212 }\r
213\r
214 return EFI_UNSUPPORTED;\r
215}\r
216\r
ea46ebbe 217EFI_STATUS\r
218BootDeviceGetType (\r
55a9f75d 219 IN EFI_DEVICE_PATH* DevicePath,\r
2ccfb71e 220 OUT ARM_BDS_LOADER_TYPE *BootType,\r
ea46ebbe 221 OUT UINT32 *Attributes\r
222 )\r
223{\r
55a9f75d
OM
224 EFI_STATUS Status;\r
225 BOOLEAN IsEfiApp;\r
226 BOOLEAN IsBootLoader;\r
227 BOOLEAN HasFDTSupport;\r
228 CHAR16* FileName;\r
229 EFI_DEVICE_PATH* PrevDevicePathNode;\r
230 EFI_DEVICE_PATH* DevicePathNode;\r
231 EFI_PHYSICAL_ADDRESS Image;\r
232 UINTN FileSize;\r
233 EFI_IMAGE_DOS_HEADER* DosHeader;\r
234 UINTN PeCoffHeaderOffset;\r
235 EFI_IMAGE_NT_HEADERS32* NtHeader;\r
236\r
237 //\r
238 // Check if the last node of the device path is a FilePath node\r
239 //\r
240 PrevDevicePathNode = NULL;\r
241 DevicePathNode = DevicePath;\r
242 while ((DevicePathNode != NULL) && !IsDevicePathEnd (DevicePathNode)) {\r
243 PrevDevicePathNode = DevicePathNode;\r
244 DevicePathNode = NextDevicePathNode (DevicePathNode);\r
245 }\r
246\r
247 if ((PrevDevicePathNode != NULL) &&\r
248 (PrevDevicePathNode->Type == MEDIA_DEVICE_PATH) &&\r
249 (PrevDevicePathNode->SubType == MEDIA_FILEPATH_DP))\r
250 {\r
251 FileName = ((FILEPATH_DEVICE_PATH*)PrevDevicePathNode)->PathName;\r
252 } else {\r
253 FileName = NULL;\r
254 }\r
ea46ebbe 255\r
256 if (FileName == NULL) {\r
257 Print(L"Is an EFI Application? ");\r
258 Status = GetHIInputBoolean (&IsEfiApp);\r
259 if (EFI_ERROR(Status)) {\r
260 return EFI_ABORTED;\r
261 }\r
262 } else if (HasFilePathEfiExtension(FileName)) {\r
263 IsEfiApp = TRUE;\r
264 } else {\r
55a9f75d
OM
265 // Check if the file exist\r
266 Status = BdsLoadImage (DevicePath, AllocateAnyPages, &Image, &FileSize);\r
267 if (!EFI_ERROR (Status)) {\r
268\r
269 DosHeader = (EFI_IMAGE_DOS_HEADER *)(UINTN) Image;\r
270 if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
271 //\r
272 // DOS image header is present,\r
273 // so read the PE header after the DOS image header.\r
274 //\r
275 PeCoffHeaderOffset = DosHeader->e_lfanew;\r
276 } else {\r
277 PeCoffHeaderOffset = 0;\r
278 }\r
279\r
280 //\r
281 // Check PE/COFF image.\r
282 //\r
283 NtHeader = (EFI_IMAGE_NT_HEADERS32 *)(UINTN) (Image + PeCoffHeaderOffset);\r
284 if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
285 IsEfiApp = FALSE;\r
286 } else {\r
287 IsEfiApp = TRUE;\r
288 }\r
289\r
290 // Free memory\r
291 gBS->FreePages (Image, EFI_SIZE_TO_PAGES(FileSize));\r
292 } else {\r
293 // If we did not manage to open it then ask for the type\r
294 Print(L"Is an EFI Application? ");\r
295 Status = GetHIInputBoolean (&IsEfiApp);\r
296 if (EFI_ERROR(Status)) {\r
297 return EFI_ABORTED;\r
298 }\r
299 }\r
ea46ebbe 300 }\r
301\r
302 if (IsEfiApp) {\r
303 Print(L"Is your application is an OS loader? ");\r
304 Status = GetHIInputBoolean (&IsBootLoader);\r
305 if (EFI_ERROR(Status)) {\r
306 return EFI_ABORTED;\r
307 }\r
308 if (!IsBootLoader) {\r
309 *Attributes |= LOAD_OPTION_CATEGORY_APP;\r
310 }\r
311 *BootType = BDS_LOADER_EFI_APPLICATION;\r
312 } else {\r
313 Print(L"Has FDT support? ");\r
314 Status = GetHIInputBoolean (&HasFDTSupport);\r
315 if (EFI_ERROR(Status)) {\r
316 return EFI_ABORTED;\r
317 }\r
318 if (HasFDTSupport) {\r
319 *BootType = BDS_LOADER_KERNEL_LINUX_FDT;\r
320 } else {\r
321 *BootType = BDS_LOADER_KERNEL_LINUX_ATAG;\r
322 }\r
323 }\r
324\r
325 return EFI_SUCCESS;\r
326}\r
327\r
328EFI_STATUS\r
329BdsLoadOptionFileSystemList (\r
330 IN OUT LIST_ENTRY* BdsLoadOptionList\r
331 )\r
332{\r
333 EFI_STATUS Status;\r
334 UINTN HandleCount;\r
335 EFI_HANDLE *HandleBuffer;\r
336 UINTN Index;\r
337 BDS_SUPPORTED_DEVICE *SupportedDevice;\r
338 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileProtocol;\r
339 EFI_FILE_HANDLE Fs;\r
340 UINTN Size;\r
341 EFI_FILE_SYSTEM_INFO* FsInfo;\r
342 EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
343\r
344 // List all the Simple File System Protocols\r
345 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
346 if (EFI_ERROR (Status)) {\r
347 return Status;\r
348 }\r
349\r
350 for (Index = 0; Index < HandleCount; Index++) {\r
351 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
352 if (!EFI_ERROR(Status)) {\r
353 // Allocate BDS Supported Device structure\r
2ccfb71e 354 SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE));\r
ea46ebbe 355\r
356 FileProtocol = NULL;\r
357 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileProtocol);\r
358 ASSERT_EFI_ERROR(Status);\r
359\r
360 FileProtocol->OpenVolume (FileProtocol, &Fs);\r
361\r
362 // Generate a Description from the file system\r
363 Size = 0;\r
364 FsInfo = NULL;\r
365 Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);\r
366 if (Status == EFI_BUFFER_TOO_SMALL) {\r
367 FsInfo = AllocatePool (Size);\r
368 Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);\r
369 }\r
370 UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"%s (%d MB)",FsInfo->VolumeLabel,(UINT32)(FsInfo->VolumeSize / (1024 * 1024)));\r
371 FreePool(FsInfo);\r
372 Fs->Close (Fs);\r
373\r
374 SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
375 SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_FILESYSTEM];\r
376\r
377 InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
378 }\r
379 }\r
380\r
381 return EFI_SUCCESS;\r
382}\r
383\r
384EFI_STATUS\r
385BdsLoadOptionFileSystemCreateDevicePath (\r
22a262c8 386 IN CHAR16* FileName,\r
ecc62d13 387 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 388 OUT BOOLEAN *RequestBootType\r
ea46ebbe 389 )\r
390{\r
391 EFI_STATUS Status;\r
392 FILEPATH_DEVICE_PATH* FilePathDevicePath;\r
74b96132 393 CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
ea46ebbe 394 UINTN BootFilePathSize;\r
395\r
22a262c8 396 Print(L"File path of the %s: ", FileName);\r
74b96132 397 Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
ea46ebbe 398 if (EFI_ERROR(Status)) {\r
399 return EFI_ABORTED;\r
400 }\r
401\r
74b96132 402 BootFilePathSize = StrSize (BootFilePath);\r
403 if (BootFilePathSize == 2) {\r
ecc62d13 404 *DevicePathNodes = NULL;\r
656416bc 405 return EFI_NOT_FOUND;\r
406 }\r
407\r
ea46ebbe 408 // Create the FilePath Device Path node\r
ecc62d13 409 FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH);\r
ea46ebbe 410 FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;\r
411 FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;\r
412 SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
413 CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);\r
ecc62d13 414 SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));\r
55a9f75d 415 *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath;\r
ea46ebbe 416\r
417 return Status;\r
418}\r
419\r
420EFI_STATUS\r
421BdsLoadOptionFileSystemUpdateDevicePath (\r
22a262c8 422 IN EFI_DEVICE_PATH *OldDevicePath,\r
423 IN CHAR16* FileName,\r
424 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 425 OUT BOOLEAN *RequestBootType\r
ea46ebbe 426 )\r
427{\r
428 EFI_STATUS Status;\r
74b96132 429 CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
ea46ebbe 430 UINTN BootFilePathSize;\r
431 FILEPATH_DEVICE_PATH* EndingDevicePath;\r
432 FILEPATH_DEVICE_PATH* FilePathDevicePath;\r
433 EFI_DEVICE_PATH* DevicePath;\r
434\r
0db25ccc 435 DevicePath = DuplicateDevicePath (OldDevicePath);\r
ea46ebbe 436\r
656416bc 437 EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);\r
438 \r
22a262c8 439 Print(L"File path of the %s: ", FileName);\r
74b96132 440 StrnCpy (BootFilePath, EndingDevicePath->PathName, BOOT_DEVICE_FILEPATH_MAX);\r
441 Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
ea46ebbe 442 if (EFI_ERROR(Status)) {\r
443 return Status;\r
444 }\r
445\r
74b96132 446 BootFilePathSize = StrSize(BootFilePath);\r
447 if (BootFilePathSize == 2) {\r
656416bc 448 *NewDevicePath = NULL;\r
449 return EFI_NOT_FOUND;\r
450 }\r
451\r
ea46ebbe 452 // Create the FilePath Device Path node\r
453 FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
454 FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;\r
455 FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;\r
456 SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
457 CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);\r
ea46ebbe 458\r
459 // Generate the new Device Path by replacing the last node by the updated node\r
460 SetDevicePathEndNode (EndingDevicePath);\r
461 *NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath);\r
462 FreePool(DevicePath);\r
463\r
656416bc 464 return EFI_SUCCESS;\r
ea46ebbe 465}\r
466\r
467BOOLEAN\r
468BdsLoadOptionFileSystemIsSupported (\r
22a262c8 469 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 470 )\r
471{\r
472 EFI_DEVICE_PATH* DevicePathNode;\r
473\r
22a262c8 474 DevicePathNode = GetLastDevicePathNode (DevicePath);\r
ea46ebbe 475\r
476 return IS_DEVICE_PATH_NODE(DevicePathNode,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP);\r
477}\r
478\r
479STATIC\r
480BOOLEAN\r
481IsParentDevicePath (\r
482 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
483 IN EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath\r
484 )\r
485{\r
486 UINTN ParentSize;\r
487 UINTN ChildSize;\r
488\r
489 ParentSize = GetDevicePathSize (ParentDevicePath);\r
490 ChildSize = GetDevicePathSize (ChildDevicePath);\r
491\r
492 if (ParentSize > ChildSize) {\r
493 return FALSE;\r
494 }\r
495\r
496 if (CompareMem (ParentDevicePath, ChildDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0) {\r
497 return FALSE;\r
498 }\r
499\r
500 return TRUE;\r
501}\r
502\r
503EFI_STATUS\r
504BdsLoadOptionMemMapList (\r
505 IN OUT LIST_ENTRY* BdsLoadOptionList\r
506 )\r
507{\r
508 EFI_STATUS Status;\r
509 UINTN HandleCount;\r
510 EFI_HANDLE *HandleBuffer;\r
511 UINTN DevicePathHandleCount;\r
512 EFI_HANDLE *DevicePathHandleBuffer;\r
513 BOOLEAN IsParent;\r
514 UINTN Index;\r
515 UINTN Index2;\r
516 BDS_SUPPORTED_DEVICE *SupportedDevice;\r
517 EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
518 EFI_DEVICE_PATH* DevicePath;\r
519\r
520 // List all the BlockIo Protocols\r
521 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
522 if (EFI_ERROR (Status)) {\r
523 return Status;\r
524 }\r
525\r
526 for (Index = 0; Index < HandleCount; Index++) {\r
527 // We only select the handle WITH a Device Path AND not part of Media (to avoid duplication with HardDisk, CDROM, etc)\r
528 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
529 if (!EFI_ERROR(Status)) {\r
530 // BlockIo is not part of Media Device Path\r
531 DevicePath = DevicePathProtocol;\r
532 while (!IsDevicePathEndType (DevicePath) && (DevicePathType (DevicePath) != MEDIA_DEVICE_PATH)) {\r
533 DevicePath = NextDevicePathNode (DevicePath);\r
534 }\r
535 if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {\r
536 continue;\r
537 }\r
538\r
539 // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child\r
540 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &DevicePathHandleCount, &DevicePathHandleBuffer);\r
541 ASSERT_EFI_ERROR (Status);\r
542 IsParent = FALSE;\r
543 for (Index2 = 0; (Index2 < DevicePathHandleCount) && !IsParent; Index2++) {\r
544 if (HandleBuffer[Index] != DevicePathHandleBuffer[Index2]) {\r
545 gBS->HandleProtocol (DevicePathHandleBuffer[Index2], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);\r
546 if (IsParentDevicePath (DevicePathProtocol, DevicePath)) {\r
547 IsParent = TRUE;\r
548 }\r
549 }\r
550 }\r
551 if (IsParent) {\r
552 continue;\r
553 }\r
554\r
555 // Allocate BDS Supported Device structure\r
556 SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));\r
557\r
558 Status = GenerateDeviceDescriptionName (HandleBuffer[Index], SupportedDevice->Description);\r
559 ASSERT_EFI_ERROR (Status);\r
560\r
561 SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
562 SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_MEMMAP];\r
563\r
564 InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
565 }\r
566 }\r
567\r
568 return EFI_SUCCESS;\r
569}\r
570\r
571EFI_STATUS\r
572BdsLoadOptionMemMapCreateDevicePath (\r
22a262c8 573 IN CHAR16* FileName,\r
ecc62d13 574 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 575 OUT BOOLEAN *RequestBootType\r
ea46ebbe 576 )\r
577{\r
22a262c8 578 EFI_STATUS Status;\r
579 MEMMAP_DEVICE_PATH *MemMapDevicePath;\r
580 CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
581 CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
ea46ebbe 582\r
22a262c8 583 Print(L"Starting Address of the %s: ", FileName);\r
584 Status = GetHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
ea46ebbe 585 if (EFI_ERROR(Status)) {\r
586 return EFI_ABORTED;\r
587 }\r
588\r
22a262c8 589 Print(L"Ending Address of the %s: ", FileName);\r
590 Status = GetHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
ea46ebbe 591 if (EFI_ERROR(Status)) {\r
592 return EFI_ABORTED;\r
593 }\r
594\r
595 // Create the MemMap Device Path Node\r
22a262c8 596 MemMapDevicePath = (MEMMAP_DEVICE_PATH*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH) + END_DEVICE_PATH_LENGTH);\r
ea46ebbe 597 MemMapDevicePath->Header.Type = HARDWARE_DEVICE_PATH;\r
598 MemMapDevicePath->Header.SubType = HW_MEMMAP_DP;\r
22a262c8 599 SetDevicePathNodeLength (MemMapDevicePath, sizeof(MEMMAP_DEVICE_PATH));\r
ea46ebbe 600 MemMapDevicePath->MemoryType = EfiBootServicesData;\r
74b96132 601 MemMapDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);\r
602 MemMapDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);\r
ea46ebbe 603\r
22a262c8 604 // Set a Device Path End Node after the Memory Map Device Path Node\r
605 SetDevicePathEndNode (MemMapDevicePath + 1);\r
55a9f75d 606 *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath;\r
ea46ebbe 607\r
608 return Status;\r
609}\r
610\r
611EFI_STATUS\r
612BdsLoadOptionMemMapUpdateDevicePath (\r
22a262c8 613 IN EFI_DEVICE_PATH *OldDevicePath,\r
614 IN CHAR16* FileName,\r
615 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 616 OUT BOOLEAN *RequestBootType\r
ea46ebbe 617 )\r
618{\r
6bab33c7 619 EFI_STATUS Status;\r
74b96132 620 CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
621 CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
6bab33c7 622 MEMMAP_DEVICE_PATH* EndingDevicePath;\r
623 EFI_DEVICE_PATH* DevicePath;\r
624\r
656416bc 625 DevicePath = DuplicateDevicePath (OldDevicePath);\r
6bab33c7 626 EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);\r
627\r
22a262c8 628 Print(L"Starting Address of the %s: ", FileName);\r
74b96132 629 UnicodeSPrint (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->StartingAddress);\r
630 Status = EditHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
6bab33c7 631 if (EFI_ERROR(Status)) {\r
632 return EFI_ABORTED;\r
633 }\r
634\r
22a262c8 635 Print(L"Ending Address of the %s: ", FileName);\r
74b96132 636 UnicodeSPrint (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->EndingAddress);\r
637 Status = EditHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
6bab33c7 638 if (EFI_ERROR(Status)) {\r
639 return EFI_ABORTED;\r
640 }\r
641\r
74b96132 642 EndingDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);\r
643 EndingDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);\r
6bab33c7 644\r
6bab33c7 645 if (EFI_ERROR(Status)) {\r
646 FreePool(DevicePath);\r
647 } else {\r
648 *NewDevicePath = DevicePath;\r
649 }\r
650\r
651 return Status;\r
ea46ebbe 652}\r
653\r
654BOOLEAN\r
655BdsLoadOptionMemMapIsSupported (\r
22a262c8 656 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 657 )\r
658{\r
659 EFI_DEVICE_PATH* DevicePathNode;\r
660\r
22a262c8 661 DevicePathNode = GetLastDevicePathNode (DevicePath);\r
ea46ebbe 662\r
663 return IS_DEVICE_PATH_NODE(DevicePathNode,HARDWARE_DEVICE_PATH,HW_MEMMAP_DP);\r
664}\r
665\r
666EFI_STATUS\r
667BdsLoadOptionPxeList (\r
668 IN OUT LIST_ENTRY* BdsLoadOptionList\r
669 )\r
670{\r
671 EFI_STATUS Status;\r
672 UINTN HandleCount;\r
673 EFI_HANDLE *HandleBuffer;\r
674 UINTN Index;\r
675 BDS_SUPPORTED_DEVICE *SupportedDevice;\r
676 EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
677 EFI_SIMPLE_NETWORK_PROTOCOL* SimpleNet;\r
678 CHAR16 DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
679 EFI_MAC_ADDRESS *Mac;\r
680\r
681 // List all the PXE Protocols\r
682 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
683 if (EFI_ERROR (Status)) {\r
684 return Status;\r
685 }\r
686\r
687 for (Index = 0; Index < HandleCount; Index++) {\r
688 // We only select the handle WITH a Device Path AND the PXE Protocol\r
689 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
690 if (!EFI_ERROR(Status)) {\r
691 // Allocate BDS Supported Device structure\r
692 SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));\r
693\r
694 Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);\r
695 if (!EFI_ERROR(Status)) {\r
696 Mac = &SimpleNet->Mode->CurrentAddress;\r
697 UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5]);\r
698 } else {\r
699 Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);\r
700 ASSERT_EFI_ERROR (Status);\r
701 }\r
702 UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"PXE on %s",DeviceDescription);\r
703\r
704 SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
705 SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_PXE];\r
706\r
707 InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
708 }\r
709 }\r
710\r
711 return EFI_SUCCESS;\r
712}\r
713\r
714EFI_STATUS\r
715BdsLoadOptionPxeCreateDevicePath (\r
22a262c8 716 IN CHAR16* FileName,\r
ecc62d13 717 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 718 OUT BOOLEAN *RequestBootType\r
ea46ebbe 719 )\r
720{\r
ecc62d13 721 *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);\r
722 SetDevicePathEndNode (*DevicePathNodes);\r
55a9f75d
OM
723\r
724 if (RequestBootType) {\r
725 *RequestBootType = FALSE;\r
726 }\r
ea46ebbe 727 return EFI_SUCCESS;\r
728}\r
729\r
730EFI_STATUS\r
731BdsLoadOptionPxeUpdateDevicePath (\r
22a262c8 732 IN EFI_DEVICE_PATH *OldDevicePath,\r
733 IN CHAR16* FileName,\r
734 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 735 OUT BOOLEAN *RequestBootType\r
ea46ebbe 736 )\r
737{\r
738 ASSERT (0);\r
55a9f75d 739 return EFI_UNSUPPORTED;\r
ea46ebbe 740}\r
741\r
742BOOLEAN\r
743BdsLoadOptionPxeIsSupported (\r
22a262c8 744 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 745 )\r
746{\r
747 EFI_STATUS Status;\r
748 EFI_HANDLE Handle;\r
749 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;\r
750 EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol;\r
751\r
22a262c8 752 Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);\r
ea46ebbe 753 if (EFI_ERROR(Status)) {\r
754 return FALSE;\r
755 }\r
756\r
757 if (!IsDevicePathEnd(RemainingDevicePath)) {\r
758 return FALSE;\r
759 }\r
760\r
761 Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);\r
762 if (EFI_ERROR (Status)) {\r
763 return FALSE;\r
764 } else {\r
765 return TRUE;\r
766 }\r
767}\r
768\r
769EFI_STATUS\r
770BdsLoadOptionTftpList (\r
771 IN OUT LIST_ENTRY* BdsLoadOptionList\r
772 )\r
773{\r
774 EFI_STATUS Status;\r
775 UINTN HandleCount;\r
776 EFI_HANDLE *HandleBuffer;\r
777 UINTN Index;\r
778 BDS_SUPPORTED_DEVICE *SupportedDevice;\r
779 EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
780 EFI_SIMPLE_NETWORK_PROTOCOL* SimpleNet;\r
781 CHAR16 DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
782 EFI_MAC_ADDRESS *Mac;\r
783\r
784 // List all the PXE Protocols\r
785 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
786 if (EFI_ERROR (Status)) {\r
787 return Status;\r
788 }\r
789\r
790 for (Index = 0; Index < HandleCount; Index++) {\r
791 // We only select the handle WITH a Device Path AND the PXE Protocol AND the TFTP Protocol (the TFTP protocol is required to start PXE)\r
792 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
793 if (!EFI_ERROR(Status)) {\r
794 // Allocate BDS Supported Device structure\r
795 SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));\r
796\r
797 Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);\r
798 if (!EFI_ERROR(Status)) {\r
799 Mac = &SimpleNet->Mode->CurrentAddress;\r
800 UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5]);\r
801 } else {\r
802 Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);\r
803 ASSERT_EFI_ERROR (Status);\r
804 }\r
b34e4db3 805 UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"TFTP on %s",DeviceDescription);\r
ea46ebbe 806\r
807 SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
808 SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];\r
809\r
810 InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
811 }\r
812 }\r
813\r
814 return EFI_SUCCESS;\r
815}\r
816\r
817EFI_STATUS\r
818BdsLoadOptionTftpCreateDevicePath (\r
22a262c8 819 IN CHAR16* FileName,\r
ecc62d13 820 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,\r
55a9f75d 821 OUT BOOLEAN *RequestBootType\r
ea46ebbe 822 )\r
823{\r
824 EFI_STATUS Status;\r
825 BOOLEAN IsDHCP;\r
826 EFI_IP_ADDRESS LocalIp;\r
827 EFI_IP_ADDRESS RemoteIp;\r
828 IPv4_DEVICE_PATH* IPv4DevicePathNode;\r
829 FILEPATH_DEVICE_PATH* FilePathDevicePath;\r
74b96132 830 CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
ea46ebbe 831 UINTN BootFilePathSize;\r
832\r
833 Print(L"Get the IP address from DHCP: ");\r
834 Status = GetHIInputBoolean (&IsDHCP);\r
835 if (EFI_ERROR(Status)) {\r
836 return EFI_ABORTED;\r
837 }\r
838\r
839 if (!IsDHCP) {\r
840 Print(L"Get the static IP address: ");\r
841 Status = GetHIInputIP (&LocalIp);\r
842 if (EFI_ERROR(Status)) {\r
843 return EFI_ABORTED;\r
844 }\r
845 }\r
846\r
847 Print(L"Get the TFTP server IP address: ");\r
848 Status = GetHIInputIP (&RemoteIp);\r
849 if (EFI_ERROR(Status)) {\r
850 return EFI_ABORTED;\r
851 }\r
852\r
22a262c8 853 Print(L"File path of the %s : ", FileName);\r
74b96132 854 Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
ea46ebbe 855 if (EFI_ERROR(Status)) {\r
856 return EFI_ABORTED;\r
857 }\r
858\r
ea46ebbe 859 BootFilePathSize = StrSize(BootFilePath);\r
74b96132 860 if (BootFilePathSize == 2) {\r
861 return EFI_NOT_FOUND;\r
862 }\r
ea46ebbe 863\r
864 // Allocate the memory for the IPv4 + File Path Device Path Nodes\r
ecc62d13 865 IPv4DevicePathNode = (IPv4_DEVICE_PATH*)AllocatePool(sizeof(IPv4_DEVICE_PATH) + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH);\r
ea46ebbe 866\r
867 // Create the IPv4 Device Path\r
868 IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH;\r
869 IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP;\r
870 SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH));\r
871 CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
872 CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
873 IPv4DevicePathNode->LocalPort = 0;\r
874 IPv4DevicePathNode->RemotePort = 0;\r
875 IPv4DevicePathNode->Protocol = EFI_IP_PROTO_TCP;\r
876 IPv4DevicePathNode->StaticIpAddress = (IsDHCP != TRUE);\r
877\r
878 // Create the FilePath Device Path node\r
879 FilePathDevicePath = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1);\r
880 FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;\r
881 FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;\r
882 SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
883 CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);\r
ea46ebbe 884\r
ecc62d13 885 // Set the End Device Path Node\r
886 SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));\r
55a9f75d 887 *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode;\r
ea46ebbe 888\r
889 return Status;\r
890}\r
891\r
892EFI_STATUS\r
893BdsLoadOptionTftpUpdateDevicePath (\r
22a262c8 894 IN EFI_DEVICE_PATH *OldDevicePath,\r
895 IN CHAR16* FileName,\r
896 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,\r
55a9f75d 897 OUT BOOLEAN *RequestBootType\r
ea46ebbe 898 )\r
899{\r
900 ASSERT (0);\r
55a9f75d 901 return EFI_UNSUPPORTED;\r
ea46ebbe 902}\r
903\r
904BOOLEAN\r
905BdsLoadOptionTftpIsSupported (\r
22a262c8 906 IN EFI_DEVICE_PATH *DevicePath\r
ea46ebbe 907 )\r
908{\r
909 EFI_STATUS Status;\r
910 EFI_HANDLE Handle;\r
911 EFI_DEVICE_PATH *RemainingDevicePath;\r
912 EFI_DEVICE_PATH *NextDevicePath;\r
913 EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol;\r
914\r
22a262c8 915 Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);\r
ea46ebbe 916 if (EFI_ERROR(Status)) {\r
917 return FALSE;\r
918 }\r
919\r
920 // Validate the Remaining Device Path\r
921 if (IsDevicePathEnd(RemainingDevicePath)) {\r
922 return FALSE;\r
923 }\r
924 if (!IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv4_DP) &&\r
925 !IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv6_DP)) {\r
926 return FALSE;\r
927 }\r
928 NextDevicePath = NextDevicePathNode (RemainingDevicePath);\r
929 if (IsDevicePathEnd(NextDevicePath)) {\r
930 return FALSE;\r
931 }\r
932 if (!IS_DEVICE_PATH_NODE(NextDevicePath,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP)) {\r
933 return FALSE;\r
934 }\r
935\r
936 Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);\r
937 if (EFI_ERROR (Status)) {\r
938 return FALSE;\r
939 } else {\r
940 return TRUE;\r
941 }\r
942}\r