mirror of https://github.com/acidanthera/audk.git
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;
|
|
}
|
|
}
|