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