+++ /dev/null
-/** @file\r
-*\r
-* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD License\r
-* which accompanies this distribution. The full text of the license may be found at\r
-* http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-\r
-#include "BdsInternal.h"\r
-\r
-#include <Library/NetLib.h>\r
-\r
-#include <Protocol/BlockIo.h>\r
-#include <Protocol/DevicePathToText.h>\r
-#include <Protocol/FirmwareVolumeBlock.h>\r
-#include <Protocol/PxeBaseCode.h>\r
-#include <Protocol/SimpleFileSystem.h>\r
-#include <Protocol/SimpleNetwork.h>\r
-#include <Protocol/Dhcp4.h>\r
-#include <Protocol/Mtftp4.h>\r
-\r
-#include <Guid/FileSystemInfo.h>\r
-\r
-#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))\r
-\r
-EFI_STATUS\r
-BdsLoadOptionFileSystemList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionFileSystemCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionFileSystemUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- );\r
-\r
-BOOLEAN\r
-BdsLoadOptionFileSystemIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionMemMapList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionMemMapCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionMemMapUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- );\r
-\r
-BOOLEAN\r
-BdsLoadOptionMemMapIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionPxeList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionPxeCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionPxeUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- );\r
-\r
-BOOLEAN\r
-BdsLoadOptionPxeIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionTftpList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionTftpCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- );\r
-\r
-EFI_STATUS\r
-BdsLoadOptionTftpUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- );\r
-\r
-BOOLEAN\r
-BdsLoadOptionTftpIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- );\r
-\r
-BDS_LOAD_OPTION_SUPPORT BdsLoadOptionSupportList[] = {\r
- {\r
- BDS_DEVICE_FILESYSTEM,\r
- BdsLoadOptionFileSystemList,\r
- BdsLoadOptionFileSystemIsSupported,\r
- BdsLoadOptionFileSystemCreateDevicePath,\r
- BdsLoadOptionFileSystemUpdateDevicePath,\r
- TRUE\r
- },\r
- {\r
- BDS_DEVICE_MEMMAP,\r
- BdsLoadOptionMemMapList,\r
- BdsLoadOptionMemMapIsSupported,\r
- BdsLoadOptionMemMapCreateDevicePath,\r
- BdsLoadOptionMemMapUpdateDevicePath,\r
- TRUE\r
- },\r
- {\r
- BDS_DEVICE_PXE,\r
- BdsLoadOptionPxeList,\r
- BdsLoadOptionPxeIsSupported,\r
- BdsLoadOptionPxeCreateDevicePath,\r
- BdsLoadOptionPxeUpdateDevicePath,\r
- FALSE\r
- },\r
- {\r
- BDS_DEVICE_TFTP,\r
- BdsLoadOptionTftpList,\r
- BdsLoadOptionTftpIsSupported,\r
- BdsLoadOptionTftpCreateDevicePath,\r
- BdsLoadOptionTftpUpdateDevicePath,\r
- TRUE\r
- }\r
-};\r
-\r
-EFI_STATUS\r
-BootDeviceListSupportedInit (\r
- IN OUT LIST_ENTRY *SupportedDeviceList\r
- )\r
-{\r
- UINTN Index;\r
-\r
- // Initialize list of supported devices\r
- InitializeListHead (SupportedDeviceList);\r
-\r
- for (Index = 0; Index < BDS_DEVICE_MAX; Index++) {\r
- BdsLoadOptionSupportList[Index].ListDevices (SupportedDeviceList);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BootDeviceListSupportedFree (\r
- IN LIST_ENTRY *SupportedDeviceList,\r
- IN BDS_SUPPORTED_DEVICE *Except\r
- )\r
-{\r
- LIST_ENTRY *Entry;\r
- BDS_SUPPORTED_DEVICE* SupportedDevice;\r
-\r
- Entry = GetFirstNode (SupportedDeviceList);\r
- while (Entry != SupportedDeviceList) {\r
- SupportedDevice = SUPPORTED_BOOT_DEVICE_FROM_LINK(Entry);\r
- Entry = RemoveEntryList (Entry);\r
- if (SupportedDevice != Except) {\r
- FreePool (SupportedDevice);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BootDeviceGetDeviceSupport (\r
- IN EFI_DEVICE_PATH *DevicePath,\r
- OUT BDS_LOAD_OPTION_SUPPORT **DeviceSupport\r
- )\r
-{\r
- UINTN Index;\r
-\r
- // Find which supported device is the most appropriate\r
- for (Index = 0; Index < BDS_DEVICE_MAX; Index++) {\r
- if (BdsLoadOptionSupportList[Index].IsSupported (DevicePath)) {\r
- *DeviceSupport = &BdsLoadOptionSupportList[Index];\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionFileSystemList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN Index;\r
- BDS_SUPPORTED_DEVICE *SupportedDevice;\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* FileProtocol;\r
- EFI_FILE_HANDLE Fs;\r
- UINTN Size;\r
- EFI_FILE_SYSTEM_INFO* FsInfo;\r
- EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
-\r
- // List all the Simple File System Protocols\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
- if (!EFI_ERROR(Status)) {\r
- // Allocate BDS Supported Device structure\r
- SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE));\r
-\r
- FileProtocol = NULL;\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileProtocol);\r
- ASSERT_EFI_ERROR(Status);\r
-\r
- FileProtocol->OpenVolume (FileProtocol, &Fs);\r
-\r
- // Generate a Description from the file system\r
- Size = 0;\r
- FsInfo = NULL;\r
- Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- FsInfo = AllocatePool (Size);\r
- Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);\r
- }\r
- UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"%s (%d MB)",FsInfo->VolumeLabel,(UINT32)(FsInfo->VolumeSize / (1024 * 1024)));\r
- FreePool(FsInfo);\r
- Fs->Close (Fs);\r
-\r
- SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
- SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_FILESYSTEM];\r
-\r
- InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionFileSystemCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FILEPATH_DEVICE_PATH* FilePathDevicePath;\r
- CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
- UINTN BootFilePathSize;\r
-\r
- Print(L"File path of the %s: ", FileName);\r
- Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
- if (EFI_ERROR(Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- BootFilePathSize = StrSize (BootFilePath);\r
- if (BootFilePathSize == 2) {\r
- *DevicePathNodes = NULL;\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- // Create the FilePath Device Path node\r
- FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH);\r
- FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;\r
- FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;\r
- SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
- CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);\r
- SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));\r
- *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath;\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionFileSystemUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
- UINTN BootFilePathSize;\r
- FILEPATH_DEVICE_PATH* EndingDevicePath;\r
- FILEPATH_DEVICE_PATH* FilePathDevicePath;\r
- EFI_DEVICE_PATH* DevicePath;\r
-\r
- DevicePath = DuplicateDevicePath (OldDevicePath);\r
-\r
- EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);\r
-\r
- Print(L"File path of the %s: ", FileName);\r
- StrnCpy (BootFilePath, EndingDevicePath->PathName, BOOT_DEVICE_FILEPATH_MAX);\r
- Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- BootFilePathSize = StrSize(BootFilePath);\r
- if (BootFilePathSize == 2) {\r
- *NewDevicePath = NULL;\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- // Create the FilePath Device Path node\r
- FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
- FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;\r
- FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;\r
- SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
- CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);\r
-\r
- // Generate the new Device Path by replacing the last node by the updated node\r
- SetDevicePathEndNode (EndingDevicePath);\r
- *NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath);\r
- FreePool(DevicePath);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Check if a boot option path is a file system boot option path or not.\r
-\r
- The device specified by the beginning of the path has to support the Simple File\r
- System protocol. Furthermore, the remaining part of the path has to be composed of\r
- a single node of type MEDIA_DEVICE_PATH and sub-type MEDIA_FILEPATH_DP.\r
-\r
- @param[in] DevicePath Complete device path of a boot option.\r
-\r
- @retval FALSE The boot option path has not been identified as that of a\r
- file system boot option.\r
- @retval TRUE The boot option path is a file system boot option.\r
-**/\r
-BOOLEAN\r
-BdsLoadOptionFileSystemIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
- EFI_DEVICE_PATH *RemainingDevicePath;\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileProtocol;\r
-\r
- Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- (VOID **)(&FileProtocol)\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP))\r
- return FALSE;\r
-\r
- return TRUE;\r
-}\r
-\r
-STATIC\r
-BOOLEAN\r
-IsParentDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath\r
- )\r
-{\r
- UINTN ParentSize;\r
- UINTN ChildSize;\r
-\r
- ParentSize = GetDevicePathSize (ParentDevicePath);\r
- ChildSize = GetDevicePathSize (ChildDevicePath);\r
-\r
- if (ParentSize > ChildSize) {\r
- return FALSE;\r
- }\r
-\r
- if (CompareMem (ParentDevicePath, ChildDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionMemMapList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN DevicePathHandleCount;\r
- EFI_HANDLE *DevicePathHandleBuffer;\r
- BOOLEAN IsParent;\r
- UINTN Index;\r
- UINTN Index2;\r
- BDS_SUPPORTED_DEVICE *SupportedDevice;\r
- EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
- EFI_DEVICE_PATH* DevicePath;\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileProtocol;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;\r
-\r
- // List all the BlockIo Protocols\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- // We only select handles WITH a Device Path AND not part of Media (to\r
- // avoid duplication with HardDisk, CDROM, etc). Skip handles used by\r
- // Simple Filesystem or used for Variable Storage.\r
-\r
-\r
- Status = gBS->HandleProtocol (HandleBuffer[Index],\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- (VOID *)&FileProtocol);\r
- if (!EFI_ERROR(Status)) {\r
- // SimpleFilesystem supported on this handle, skip\r
- continue;\r
- }\r
-\r
- Status = gBS->HandleProtocol (HandleBuffer[Index],\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- (VOID *)&FvbProtocol);\r
- if (!EFI_ERROR(Status)) {\r
- // Firmware Volme Block / Variable storage supported on this handle, skip\r
- continue;\r
- }\r
-\r
- Status = gBS->HandleProtocol (HandleBuffer[Index],\r
- &gEfiFirmwareVolumeBlock2ProtocolGuid,\r
- (VOID *)&FvbProtocol);\r
- if (!EFI_ERROR(Status)) {\r
- // Firmware Volme Block / Variable storage supported on this handle, skip\r
- continue;\r
- }\r
-\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
- if (!EFI_ERROR(Status)) {\r
- // BlockIo is not part of Media Device Path\r
- DevicePath = DevicePathProtocol;\r
- while (!IsDevicePathEndType (DevicePath) && (DevicePathType (DevicePath) != MEDIA_DEVICE_PATH)) {\r
- DevicePath = NextDevicePathNode (DevicePath);\r
- }\r
- if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {\r
- continue;\r
- }\r
-\r
- // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &DevicePathHandleCount, &DevicePathHandleBuffer);\r
- ASSERT_EFI_ERROR (Status);\r
- IsParent = FALSE;\r
- for (Index2 = 0; (Index2 < DevicePathHandleCount) && !IsParent; Index2++) {\r
- if (HandleBuffer[Index] != DevicePathHandleBuffer[Index2]) {\r
- gBS->HandleProtocol (DevicePathHandleBuffer[Index2], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);\r
- if (IsParentDevicePath (DevicePathProtocol, DevicePath)) {\r
- IsParent = TRUE;\r
- }\r
- }\r
- }\r
- if (IsParent) {\r
- continue;\r
- }\r
-\r
- // Allocate BDS Supported Device structure\r
- SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));\r
-\r
- Status = GenerateDeviceDescriptionName (HandleBuffer[Index], SupportedDevice->Description);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
- SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_MEMMAP];\r
-\r
- InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionMemMapCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- )\r
-{\r
- EFI_STATUS Status;\r
- MEMMAP_DEVICE_PATH *MemMapDevicePath;\r
- CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
- CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
-\r
- Print(L"Starting Address of the %s: ", FileName);\r
- Status = GetHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
- if (EFI_ERROR(Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Print(L"Ending Address of the %s: ", FileName);\r
- Status = GetHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
- if (EFI_ERROR(Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- // Create the MemMap Device Path Node\r
- MemMapDevicePath = (MEMMAP_DEVICE_PATH*)AllocatePool (sizeof(MEMMAP_DEVICE_PATH) + END_DEVICE_PATH_LENGTH);\r
- MemMapDevicePath->Header.Type = HARDWARE_DEVICE_PATH;\r
- MemMapDevicePath->Header.SubType = HW_MEMMAP_DP;\r
- SetDevicePathNodeLength (MemMapDevicePath, sizeof(MEMMAP_DEVICE_PATH));\r
- MemMapDevicePath->MemoryType = EfiBootServicesData;\r
- MemMapDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);\r
- MemMapDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);\r
-\r
- // Set a Device Path End Node after the Memory Map Device Path Node\r
- SetDevicePathEndNode (MemMapDevicePath + 1);\r
- *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath;\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionMemMapUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CHAR16 StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
- CHAR16 StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];\r
- MEMMAP_DEVICE_PATH* EndingDevicePath;\r
- EFI_DEVICE_PATH* DevicePath;\r
-\r
- DevicePath = DuplicateDevicePath (OldDevicePath);\r
- EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);\r
-\r
- Print(L"Starting Address of the %s: ", FileName);\r
- UnicodeSPrint (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->StartingAddress);\r
- Status = EditHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
- if (EFI_ERROR(Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Print(L"Ending Address of the %s: ", FileName);\r
- UnicodeSPrint (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->EndingAddress);\r
- Status = EditHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX);\r
- if (EFI_ERROR(Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- EndingDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);\r
- EndingDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);\r
-\r
- if (EFI_ERROR(Status)) {\r
- FreePool(DevicePath);\r
- } else {\r
- *NewDevicePath = DevicePath;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Check if a boot option path is a memory map boot option path or not.\r
-\r
- The device specified by the beginning of the path has to support the BlockIo\r
- protocol. Furthermore, the remaining part of the path has to be composed of\r
- a single node of type HARDWARE_DEVICE_PATH and sub-type HW_MEMMAP_DP.\r
-\r
- @param[in] DevicePath Complete device path of a boot option.\r
-\r
- @retval FALSE The boot option path has not been identified as that of a\r
- memory map boot option.\r
- @retval TRUE The boot option path is a a memory map boot option.\r
-**/\r
-BOOLEAN\r
-BdsLoadOptionMemMapIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
- EFI_DEVICE_PATH *RemainingDevicePath;\r
- EFI_BLOCK_IO_PROTOCOL *BlockIoProtocol;\r
-\r
- Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiBlockIoProtocolGuid,\r
- (VOID **)(&BlockIoProtocol)\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP))\r
- return FALSE;\r
-\r
- return TRUE;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionPxeList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN Index;\r
- BDS_SUPPORTED_DEVICE *SupportedDevice;\r
- EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;\r
- EFI_SIMPLE_NETWORK_PROTOCOL* SimpleNet;\r
- CHAR16 DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
- EFI_MAC_ADDRESS *Mac;\r
-\r
- // List all the PXE Protocols\r
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- // We only select the handle WITH a Device Path AND the PXE Protocol\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);\r
- if (!EFI_ERROR(Status)) {\r
- // Allocate BDS Supported Device structure\r
- SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));\r
-\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleNetworkProtocolGuid, (VOID **)&SimpleNet);\r
- if (!EFI_ERROR(Status)) {\r
- Mac = &SimpleNet->Mode->CurrentAddress;\r
- 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
- } else {\r
- Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"PXE on %s",DeviceDescription);\r
-\r
- SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
- SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_PXE];\r
-\r
- InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionPxeCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- )\r
-{\r
- *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);\r
- SetDevicePathEndNode (*DevicePathNodes);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Update the parameters of a Pxe boot option\r
-\r
- @param[in] OldDevicePath Current complete device path of the Pxe boot option.\r
- This has to be a valid complete Pxe boot option path.\r
- @param[in] FileName Description of the file the path is asked for\r
- @param[out] NewDevicePath Pointer to the new complete device path.\r
-\r
- @retval EFI_SUCCESS Update completed\r
- @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource\r
-**/\r
-EFI_STATUS\r
-BdsLoadOptionPxeUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- )\r
-{\r
- //\r
- // Make a copy of the complete device path that is made of :\r
- // the device path of the device supporting the Pxe base code protocol\r
- // followed by an end node.\r
- //\r
- *NewDevicePath = DuplicateDevicePath (OldDevicePath);\r
- if (*NewDevicePath == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
-}\r
-\r
-BOOLEAN\r
-BdsLoadOptionPxeIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
- EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;\r
- EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol;\r
-\r
- Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);\r
- if (EFI_ERROR(Status)) {\r
- return FALSE;\r
- }\r
-\r
- if (!IsDevicePathEnd(RemainingDevicePath)) {\r
- return FALSE;\r
- }\r
-\r
- Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- } else {\r
- return TRUE;\r
- }\r
-}\r
-\r
-/**\r
- Add to the list of boot devices the devices allowing a TFTP boot\r
-\r
- @param[in] BdsLoadOptionList List of devices to boot from\r
-\r
- @retval EFI_SUCCESS Update completed\r
- @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource\r
-**/\r
-EFI_STATUS\r
-BdsLoadOptionTftpList (\r
- IN OUT LIST_ENTRY* BdsLoadOptionList\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- EFI_HANDLE Handle;\r
- UINTN Index;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol;\r
- VOID *Interface;\r
- EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetworkProtocol;\r
- BDS_SUPPORTED_DEVICE *SupportedDevice;\r
- EFI_MAC_ADDRESS *Mac;\r
-\r
- //\r
- // List all the handles on which the Simple Network Protocol is installed.\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiSimpleNetworkProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Handle = HandleBuffer[Index];\r
- //\r
- // We select the handles that support :\r
- // . the Device Path Protocol\r
- // . the MTFTP4 Protocol\r
- //\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **)&DevicePathProtocol\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiMtftp4ServiceBindingProtocolGuid,\r
- &Interface\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiSimpleNetworkProtocolGuid,\r
- (VOID **)&SimpleNetworkProtocol\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- // Allocate BDS Supported Device structure\r
- SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof (BDS_SUPPORTED_DEVICE));\r
- if (SupportedDevice == NULL) {\r
- continue;\r
- }\r
-\r
- Mac = &SimpleNetworkProtocol->Mode->CurrentAddress;\r
- UnicodeSPrint (\r
- SupportedDevice->Description,\r
- BOOT_DEVICE_DESCRIPTION_MAX,\r
- L"TFTP on MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",\r
- Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], Mac->Addr[3], Mac->Addr[4], Mac->Addr[5]\r
- );\r
-\r
- SupportedDevice->DevicePathProtocol = DevicePathProtocol;\r
- SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_TFTP];\r
-\r
- InsertTailList (BdsLoadOptionList, &SupportedDevice->Link);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BdsLoadOptionTftpCreateDevicePath (\r
- IN CHAR16* FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN IsDHCP;\r
- EFI_IP_ADDRESS LocalIp;\r
- EFI_IP_ADDRESS SubnetMask;\r
- EFI_IP_ADDRESS GatewayIp;\r
- EFI_IP_ADDRESS RemoteIp;\r
- IPv4_DEVICE_PATH *IPv4DevicePathNode;\r
- FILEPATH_DEVICE_PATH *FilePathDevicePath;\r
- CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
- UINTN BootFilePathSize;\r
-\r
- Print (L"Get the IP address from DHCP: ");\r
- Status = GetHIInputBoolean (&IsDHCP);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (!IsDHCP) {\r
- Print (L"Local static IP address: ");\r
- Status = GetHIInputIP (&LocalIp);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- Print (L"Get the network mask: ");\r
- Status = GetHIInputIP (&SubnetMask);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- Print (L"Get the gateway IP address: ");\r
- Status = GetHIInputIP (&GatewayIp);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
-\r
- Print (L"Get the TFTP server IP address: ");\r
- Status = GetHIInputIP (&RemoteIp);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- Print (L"File path of the %s : ", FileName);\r
- Status = GetHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- BootFilePathSize = StrSize(BootFilePath);\r
- if (BootFilePathSize == 2) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- // Allocate the memory for the IPv4 + File Path Device Path Nodes\r
- IPv4DevicePathNode = (IPv4_DEVICE_PATH*)AllocatePool(sizeof(IPv4_DEVICE_PATH) + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize + END_DEVICE_PATH_LENGTH);\r
-\r
- // Create the IPv4 Device Path\r
- IPv4DevicePathNode->Header.Type = MESSAGING_DEVICE_PATH;\r
- IPv4DevicePathNode->Header.SubType = MSG_IPv4_DP;\r
- SetDevicePathNodeLength (&IPv4DevicePathNode->Header, sizeof(IPv4_DEVICE_PATH));\r
-\r
- if (!IsDHCP) {\r
- CopyMem (&IPv4DevicePathNode->LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&IPv4DevicePathNode->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&IPv4DevicePathNode->GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
- }\r
-\r
- CopyMem (&IPv4DevicePathNode->RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
- IPv4DevicePathNode->LocalPort = 0;\r
- IPv4DevicePathNode->RemotePort = 0;\r
- IPv4DevicePathNode->Protocol = EFI_IP_PROTO_TCP;\r
- IPv4DevicePathNode->StaticIpAddress = (IsDHCP != TRUE);\r
-\r
- // Create the FilePath Device Path node\r
- FilePathDevicePath = (FILEPATH_DEVICE_PATH*)(IPv4DevicePathNode + 1);\r
- FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;\r
- FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;\r
- SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);\r
- CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);\r
-\r
- // Set the End Device Path Node\r
- SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));\r
- *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode;\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Update the parameters of a TFTP boot option\r
-\r
- The function asks sequentially to update the IPv4 parameters as well as the boot file path,\r
- providing the previously set value if any.\r
-\r
- @param[in] OldDevicePath Current complete device path of the Tftp boot option.\r
- This has to be a valid complete Tftp boot option path.\r
- By complete, we mean that it is not only the Tftp\r
- specific end part built by the\r
- "BdsLoadOptionTftpCreateDevicePath()" function.\r
- This path is handled as read only.\r
- @param[in] FileName Description of the file the path is asked for\r
- @param[out] NewDevicePath Pointer to the new complete device path.\r
-\r
- @retval EFI_SUCCESS Update completed\r
- @retval EFI_ABORTED Update aborted by the user\r
- @retval EFI_OUT_OF_RESOURCES Fail to perform the update due to lack of resource\r
-**/\r
-EFI_STATUS\r
-BdsLoadOptionTftpUpdateDevicePath (\r
- IN EFI_DEVICE_PATH *OldDevicePath,\r
- IN CHAR16 *FileName,\r
- OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH *DevicePath;\r
- EFI_DEVICE_PATH *DevicePathNode;\r
- UINT8 *Ipv4NodePtr;\r
- IPv4_DEVICE_PATH Ipv4Node;\r
- BOOLEAN IsDHCP;\r
- EFI_IP_ADDRESS OldIp;\r
- EFI_IP_ADDRESS OldSubnetMask;\r
- EFI_IP_ADDRESS OldGatewayIp;\r
- EFI_IP_ADDRESS LocalIp;\r
- EFI_IP_ADDRESS SubnetMask;\r
- EFI_IP_ADDRESS GatewayIp;\r
- EFI_IP_ADDRESS RemoteIp;\r
- UINT8 *FileNodePtr;\r
- CHAR16 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];\r
- UINTN PathSize;\r
- UINTN BootFilePathSize;\r
- FILEPATH_DEVICE_PATH *NewFilePathNode;\r
-\r
- Ipv4NodePtr = NULL;\r
-\r
- //\r
- // Make a copy of the complete device path that is made of :\r
- // the device path of the device that support the Simple Network protocol\r
- // followed by an IPv4 node (type IPv4_DEVICE_PATH),\r
- // followed by a file path node (type FILEPATH_DEVICE_PATH) and ended up\r
- // by an end node. The IPv6 case is not handled yet.\r
- //\r
-\r
- DevicePath = DuplicateDevicePath (OldDevicePath);\r
- if (DevicePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Because of the check done by "BdsLoadOptionTftpIsSupported()" prior to the\r
- // call to this function, we know that the device path ends with an IPv4 node\r
- // followed by a file path node and finally an end node. To get the address of\r
- // the last IPv4 node, we loop over the whole device path, noting down the\r
- // address of each encountered IPv4 node.\r
- //\r
-\r
- for (DevicePathNode = DevicePath;\r
- !IsDevicePathEnd (DevicePathNode);\r
- DevicePathNode = NextDevicePathNode (DevicePathNode))\r
- {\r
- if (IS_DEVICE_PATH_NODE (DevicePathNode, MESSAGING_DEVICE_PATH, MSG_IPv4_DP)) {\r
- Ipv4NodePtr = (UINT8*)DevicePathNode;\r
- }\r
- }\r
-\r
- // Copy for alignment of the IPv4 node data\r
- CopyMem (&Ipv4Node, Ipv4NodePtr, sizeof (IPv4_DEVICE_PATH));\r
-\r
- Print (L"Get the IP address from DHCP: ");\r
- Status = GetHIInputBoolean (&IsDHCP);\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- if (!IsDHCP) {\r
- Print (L"Local static IP address: ");\r
- if (Ipv4Node.StaticIpAddress) {\r
- CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
- Status = EditHIInputIP (&OldIp, &LocalIp);\r
- } else {\r
- Status = GetHIInputIP (&LocalIp);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- Print (L"Get the network mask: ");\r
- if (Ipv4Node.StaticIpAddress) {\r
- CopyMem (&OldSubnetMask.v4, &Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
- Status = EditHIInputIP (&OldSubnetMask, &SubnetMask);\r
- } else {\r
- Status = GetHIInputIP (&SubnetMask);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- Print (L"Get the gateway IP address: ");\r
- if (Ipv4Node.StaticIpAddress) {\r
- CopyMem (&OldGatewayIp.v4, &Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
- Status = EditHIInputIP (&OldGatewayIp, &GatewayIp);\r
- } else {\r
- Status = GetHIInputIP (&GatewayIp);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
- }\r
-\r
- Print (L"TFTP server IP address: ");\r
- // Copy remote IPv4 address into IPv4 or IPv6 union\r
- CopyMem (&OldIp.v4, &Ipv4Node.RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
-\r
- Status = EditHIInputIP (&OldIp, &RemoteIp);\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
-\r
- // Get the path of the boot file and its size in number of bytes\r
- FileNodePtr = Ipv4NodePtr + sizeof (IPv4_DEVICE_PATH);\r
- BootFilePathSize = DevicePathNodeLength (FileNodePtr) - SIZE_OF_FILEPATH_DEVICE_PATH;\r
-\r
- //\r
- // Ask for update of the boot file path\r
- //\r
- do {\r
- // Copy for 2-byte alignment of the Unicode string\r
- CopyMem (\r
- BootFilePath, FileNodePtr + SIZE_OF_FILEPATH_DEVICE_PATH,\r
- MIN (BootFilePathSize, BOOT_DEVICE_FILEPATH_MAX)\r
- );\r
- BootFilePath[BOOT_DEVICE_FILEPATH_MAX - 1] = L'\0';\r
-\r
- Print (L"File path of the %s: ", FileName);\r
- Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);\r
- if (EFI_ERROR (Status)) {\r
- goto ErrorExit;\r
- }\r
- PathSize = StrSize (BootFilePath);\r
- if (PathSize > 2) {\r
- break;\r
- }\r
- // Empty string, give the user another try\r
- Print (L"Empty string - Invalid path\n");\r
- } while (PathSize <= 2) ;\r
-\r
- //\r
- // Update the IPv4 node. IPv6 case not handled yet.\r
- //\r
- if (IsDHCP) {\r
- Ipv4Node.StaticIpAddress = FALSE;\r
- ZeroMem (&Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
- ZeroMem (&Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
- ZeroMem (&Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));\r
- } else {\r
- Ipv4Node.StaticIpAddress = TRUE;\r
- CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Ipv4Node.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Ipv4Node.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
- }\r
-\r
- CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH));\r
-\r
- //\r
- // Create the new file path node\r
- //\r
- NewFilePathNode = (FILEPATH_DEVICE_PATH*)AllocatePool (\r
- SIZE_OF_FILEPATH_DEVICE_PATH +\r
- PathSize\r
- );\r
- NewFilePathNode->Header.Type = MEDIA_DEVICE_PATH;\r
- NewFilePathNode->Header.SubType = MEDIA_FILEPATH_DP;\r
- SetDevicePathNodeLength (\r
- NewFilePathNode,\r
- SIZE_OF_FILEPATH_DEVICE_PATH + PathSize\r
- );\r
- CopyMem (NewFilePathNode->PathName, BootFilePath, PathSize);\r
-\r
- //\r
- // Generate the new Device Path by replacing the file path node at address\r
- // "FileNodePtr" by the new one "NewFilePathNode" and return its address.\r
- //\r
- SetDevicePathEndNode (FileNodePtr);\r
- *NewDevicePath = AppendDevicePathNode (\r
- DevicePath,\r
- (CONST EFI_DEVICE_PATH_PROTOCOL*)NewFilePathNode\r
- );\r
-\r
-ErrorExit:\r
- if (DevicePath != NULL) {\r
- FreePool (DevicePath) ;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-BOOLEAN\r
-BdsLoadOptionTftpIsSupported (\r
- IN EFI_DEVICE_PATH *DevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
- EFI_DEVICE_PATH *RemainingDevicePath;\r
- EFI_DEVICE_PATH *NextDevicePath;\r
- EFI_PXE_BASE_CODE_PROTOCOL *PxeBcProtocol;\r
-\r
- Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);\r
- if (EFI_ERROR(Status)) {\r
- return FALSE;\r
- }\r
-\r
- // Validate the Remaining Device Path\r
- if (IsDevicePathEnd(RemainingDevicePath)) {\r
- return FALSE;\r
- }\r
- if (!IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv4_DP) &&\r
- !IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv6_DP)) {\r
- return FALSE;\r
- }\r
- NextDevicePath = NextDevicePathNode (RemainingDevicePath);\r
- if (IsDevicePathEnd(NextDevicePath)) {\r
- return FALSE;\r
- }\r
- if (!IS_DEVICE_PATH_NODE(NextDevicePath,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP)) {\r
- return FALSE;\r
- }\r
-\r
- Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- } else {\r
- return TRUE;\r
- }\r
-}\r