mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 09:12:31 +00:00 
			
		
		
		
	Replaced the function BdsLoadApplication() by two explicit functions that load the EFI application either by its GUID or its Name. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <Olivier.Martin@arm.com> Reviewed-by: Ronald Cron <Ronald.Cron@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17966 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			254 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
*
 | 
						|
*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
 | 
						|
*
 | 
						|
*  This program and the accompanying materials
 | 
						|
*  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
*  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
*  http://opensource.org/licenses/bsd-license.php
 | 
						|
*
 | 
						|
*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
*
 | 
						|
**/
 | 
						|
 | 
						|
#include "BdsInternal.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Locate an EFI application in a the Firmware Volumes by its Name
 | 
						|
 | 
						|
  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume
 | 
						|
  @param  DevicePath            EFI Device Path of the EFI application
 | 
						|
 | 
						|
  @return EFI_SUCCESS           The function completed successfully.
 | 
						|
  @return EFI_NOT_FOUND         The protocol could not be located.
 | 
						|
  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
LocateEfiApplicationInFvByName (
 | 
						|
  IN  CONST CHAR16*             EfiAppName,
 | 
						|
  OUT EFI_DEVICE_PATH           **DevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  VOID                          *Key;
 | 
						|
  EFI_STATUS                    Status, FileStatus;
 | 
						|
  EFI_GUID                      NameGuid;
 | 
						|
  EFI_FV_FILETYPE               FileType;
 | 
						|
  EFI_FV_FILE_ATTRIBUTES        Attributes;
 | 
						|
  UINTN                         Size;
 | 
						|
  UINTN                         UiStringLen;
 | 
						|
  CHAR16                        *UiSection;
 | 
						|
  UINT32                        Authentication;
 | 
						|
  EFI_DEVICE_PATH               *FvDevicePath;
 | 
						|
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;
 | 
						|
  EFI_HANDLE                    *HandleBuffer;
 | 
						|
  UINTN                         NumberOfHandles;
 | 
						|
  UINTN                         Index;
 | 
						|
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
 | 
						|
 | 
						|
  ASSERT (DevicePath != NULL);
 | 
						|
 | 
						|
  // Length of FilePath
 | 
						|
  UiStringLen = StrLen (EfiAppName);
 | 
						|
 | 
						|
  // Locate all the Firmware Volume protocols.
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
                   ByProtocol,
 | 
						|
                   &gEfiFirmwareVolume2ProtocolGuid,
 | 
						|
                   NULL,
 | 
						|
                   &NumberOfHandles,
 | 
						|
                   &HandleBuffer
 | 
						|
                   );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  *DevicePath = NULL;
 | 
						|
 | 
						|
  // Looking for FV with ACPI storage file
 | 
						|
  for (Index = 0; Index < NumberOfHandles; Index++) {
 | 
						|
    //
 | 
						|
    // Get the protocol on this handle
 | 
						|
    // This should not fail because of LocateHandleBuffer
 | 
						|
    //
 | 
						|
    Status = gBS->HandleProtocol (
 | 
						|
                     HandleBuffer[Index],
 | 
						|
                     &gEfiFirmwareVolume2ProtocolGuid,
 | 
						|
                     (VOID**) &FvInstance
 | 
						|
                     );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      goto FREE_HANDLE_BUFFER;
 | 
						|
    }
 | 
						|
 | 
						|
    // Allocate Key
 | 
						|
    Key = AllocatePool (FvInstance->KeySize);
 | 
						|
    ASSERT (Key != NULL);
 | 
						|
    ZeroMem (Key, FvInstance->KeySize);
 | 
						|
 | 
						|
    do {
 | 
						|
      // Search in all files
 | 
						|
      FileType = EFI_FV_FILETYPE_ALL;
 | 
						|
 | 
						|
      Status = FvInstance->GetNextFile (FvInstance, Key, &FileType, &NameGuid, &Attributes, &Size);
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        UiSection = NULL;
 | 
						|
        FileStatus = FvInstance->ReadSection (
 | 
						|
                      FvInstance,
 | 
						|
                      &NameGuid,
 | 
						|
                      EFI_SECTION_USER_INTERFACE,
 | 
						|
                      0,
 | 
						|
                      (VOID **)&UiSection,
 | 
						|
                      &Size,
 | 
						|
                      &Authentication
 | 
						|
                      );
 | 
						|
        if (!EFI_ERROR (FileStatus)) {
 | 
						|
          if (StrnCmp (EfiAppName, UiSection, UiStringLen) == 0) {
 | 
						|
            //
 | 
						|
            // We found a UiString match.
 | 
						|
            //
 | 
						|
            Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
 | 
						|
 | 
						|
            // Generate the Device Path for the file
 | 
						|
            EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
 | 
						|
            *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
 | 
						|
            ASSERT (*DevicePath != NULL);
 | 
						|
 | 
						|
            FreePool (Key);
 | 
						|
            FreePool (UiSection);
 | 
						|
            FreePool (HandleBuffer);
 | 
						|
            return FileStatus;
 | 
						|
          }
 | 
						|
          FreePool (UiSection);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } while (!EFI_ERROR (Status));
 | 
						|
 | 
						|
    FreePool (Key);
 | 
						|
  }
 | 
						|
 | 
						|
FREE_HANDLE_BUFFER:
 | 
						|
  FreePool (HandleBuffer);
 | 
						|
  return EFI_NOT_FOUND;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Locate an EFI application in a the Firmware Volumes by its GUID
 | 
						|
 | 
						|
  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume
 | 
						|
  @param  DevicePath            EFI Device Path of the EFI application
 | 
						|
 | 
						|
  @return EFI_SUCCESS           The function completed successfully.
 | 
						|
  @return EFI_NOT_FOUND         The protocol could not be located.
 | 
						|
  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
LocateEfiApplicationInFvByGuid (
 | 
						|
  IN  CONST EFI_GUID            *EfiAppGuid,
 | 
						|
  OUT EFI_DEVICE_PATH           **DevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  EFI_DEVICE_PATH               *FvDevicePath;
 | 
						|
  EFI_HANDLE                    *HandleBuffer;
 | 
						|
  UINTN                         NumberOfHandles;
 | 
						|
  UINTN                         Index;
 | 
						|
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
 | 
						|
  EFI_FV_FILE_ATTRIBUTES        Attributes;
 | 
						|
  UINT32                        AuthenticationStatus;
 | 
						|
  EFI_FV_FILETYPE               Type;
 | 
						|
  UINTN                         Size;
 | 
						|
  CHAR16                        *UiSection;
 | 
						|
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath;
 | 
						|
 | 
						|
  ASSERT (DevicePath != NULL);
 | 
						|
 | 
						|
  // Locate all the Firmware Volume protocols.
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
                   ByProtocol,
 | 
						|
                   &gEfiFirmwareVolume2ProtocolGuid,
 | 
						|
                   NULL,
 | 
						|
                   &NumberOfHandles,
 | 
						|
                   &HandleBuffer
 | 
						|
                   );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  *DevicePath = NULL;
 | 
						|
 | 
						|
  // Looking for FV with ACPI storage file
 | 
						|
  for (Index = 0; Index < NumberOfHandles; Index++) {
 | 
						|
    //
 | 
						|
    // Get the protocol on this handle
 | 
						|
    // This should not fail because of LocateHandleBuffer
 | 
						|
    //
 | 
						|
    Status = gBS->HandleProtocol (
 | 
						|
                     HandleBuffer[Index],
 | 
						|
                     &gEfiFirmwareVolume2ProtocolGuid,
 | 
						|
                     (VOID**) &FvInstance
 | 
						|
                     );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      goto FREE_HANDLE_BUFFER;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = FvInstance->ReadFile (
 | 
						|
                  FvInstance,
 | 
						|
                  EfiAppGuid,
 | 
						|
                  NULL,
 | 
						|
                  &Size,
 | 
						|
                  &Type,
 | 
						|
                  &Attributes,
 | 
						|
                  &AuthenticationStatus
 | 
						|
                  );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // Skip if no EFI application file in the FV
 | 
						|
      //
 | 
						|
      continue;
 | 
						|
    } else {
 | 
						|
      UiSection = NULL;
 | 
						|
      Status = FvInstance->ReadSection (
 | 
						|
                    FvInstance,
 | 
						|
                    EfiAppGuid,
 | 
						|
                    EFI_SECTION_USER_INTERFACE,
 | 
						|
                    0,
 | 
						|
                    (VOID **)&UiSection,
 | 
						|
                    &Size,
 | 
						|
                    &AuthenticationStatus
 | 
						|
                    );
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        //
 | 
						|
        // Create the EFI Device Path for the application using the Filename of the application
 | 
						|
        //
 | 
						|
        *DevicePath = FileDevicePath (HandleBuffer[Index], UiSection);
 | 
						|
      } else {
 | 
						|
        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID**)&FvDevicePath);
 | 
						|
        ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
        //
 | 
						|
        // Create the EFI Device Path for the application using the EFI GUID of the application
 | 
						|
        //
 | 
						|
        EfiInitializeFwVolDevicepathNode (&FvFileDevicePath, EfiAppGuid);
 | 
						|
 | 
						|
        *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FvFileDevicePath);
 | 
						|
        ASSERT (*DevicePath != NULL);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
FREE_HANDLE_BUFFER:
 | 
						|
  //
 | 
						|
  // Free any allocated buffers
 | 
						|
  //
 | 
						|
  FreePool (HandleBuffer);
 | 
						|
 | 
						|
  if (*DevicePath == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  } else {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
}
 |