From ccb66799e390788fbdb1e5ae74984957717a9c0e Mon Sep 17 00:00:00 2001 From: Ruiyu Ni Date: Tue, 17 Nov 2015 10:10:54 +0000 Subject: [PATCH] MdeModulePkg: Support to expand File device path To support platform recovery, File device path expanding capability is added. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Reviewed-by: Sunny Wang git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18858 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/UefiBootManagerLib/BmBoot.c | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c index aef2e7bbdc..70ec2164f0 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c @@ -1072,6 +1072,76 @@ BmExpandUsbDevicePath ( return FileBuffer; } +/** + Expand File-path device path node to be full device path in platform. + + @param FilePath The device path pointing to a load option. + It could be a short-form device path. + @param FullPath Return the full device path of the load option after + short-form device path expanding. + Caller is responsible to free it. + @param FileSize Return the load option size. + + @return The load option buffer. Caller is responsible to free the memory. +**/ +VOID * +BmExpandFileDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, + OUT UINTN *FileSize + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN HandleCount; + EFI_HANDLE *Handles; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + UINTN MediaType; + EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; + VOID *FileBuffer; + UINT32 AuthenticationStatus; + + EfiBootManagerConnectAll (); + Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles); + if (EFI_ERROR (Status)) { + HandleCount = 0; + Handles = NULL; + } + + // + // Enumerate all removable media devices followed by all fixed media devices, + // followed by media devices which don't layer on block io. + // + for (MediaType = 0; MediaType < 3; MediaType++) { + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol (Handles[Index], &gEfiBlockIoProtocolGuid, (VOID *) &BlockIo); + if (EFI_ERROR (Status)) { + BlockIo = NULL; + } + if ((MediaType == 0 && BlockIo != NULL && BlockIo->Media->RemovableMedia) || + (MediaType == 1 && BlockIo != NULL && !BlockIo->Media->RemovableMedia) || + (MediaType == 2 && BlockIo == NULL) + ) { + FullDevicePath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), FilePath); + FileBuffer = GetFileBufferByFilePath (TRUE, FullDevicePath, FileSize, &AuthenticationStatus); + if (FileBuffer != NULL) { + *FullPath = FullDevicePath; + FreePool (Handles); + return FileBuffer; + } + FreePool (FullDevicePath); + } + } + } + + if (Handles != NULL) { + FreePool (Handles); + } + + *FullPath = NULL; + return NULL; +} + /** Save the partition DevicePath to the CachedDevicePath as the first instance. @@ -1473,6 +1543,12 @@ BmGetLoadOptionBuffer ( // Expand the Harddrive device path // return BmExpandPartitionDevicePath (FilePath, FullPath, FileSize); + } else if ((DevicePathType (FilePath) == MEDIA_DEVICE_PATH) && + (DevicePathSubType (FilePath) == MEDIA_FILEPATH_DP)) { + // + // Expand the File-path device path + // + return BmExpandFileDevicePath (FilePath, FullPath, FileSize); } else { for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) { if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&