192 lines
5.3 KiB
C
192 lines
5.3 KiB
C
/** @file
|
|
Load EFI driver from Firmware Volume.
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2020, Insyde Software Corporation. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "L05DxeServiceBody.h"
|
|
|
|
/**
|
|
Load EFI driver from Firmware Volume by GUID.
|
|
|
|
@param NameGuid GUID File Name
|
|
|
|
@retval None
|
|
**/
|
|
EFI_STATUS
|
|
L05LoadEfiDriverFromFv (
|
|
IN EFI_GUID *NameGuid
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN HandleCount;
|
|
EFI_HANDLE *HandleBuffer;
|
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
|
|
EFI_FV_FILETYPE Type;
|
|
UINTN Size;
|
|
EFI_FV_FILE_ATTRIBUTES Attributes;
|
|
UINT32 AuthenticationStatus;
|
|
UINTN Index;
|
|
EFI_HANDLE ImageHandle;
|
|
EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
|
|
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FwVolFilePathNode;
|
|
H2O_BDS_SERVICES_PROTOCOL *BdsServices;
|
|
H2O_BDS_LOAD_OPTION *BdsLoadOption;
|
|
CHAR16 *OsRecoveryOptionalData;
|
|
UINTN ExitDataSize;
|
|
CHAR16 *ExitData;
|
|
|
|
Status = EFI_SUCCESS;
|
|
HandleCount = 0;
|
|
HandleBuffer = NULL;
|
|
Type = 0;
|
|
Size = 0;
|
|
Attributes = 0;
|
|
AuthenticationStatus = 0;
|
|
Index = 0;
|
|
FileDevicePath = NULL;
|
|
BdsServices = NULL;
|
|
BdsLoadOption = NULL;
|
|
OsRecoveryOptionalData = NULL;
|
|
ExitDataSize = 0;
|
|
ExitData = NULL;
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiFirmwareVolume2ProtocolGuid,
|
|
NULL,
|
|
&HandleCount,
|
|
&HandleBuffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status) || HandleCount == 0) {
|
|
return Status;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gH2OBdsServicesProtocolGuid,
|
|
NULL,
|
|
(VOID **) &BdsServices
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (HandleBuffer);
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Loop through all the Firmware Volumes looking for the GUID Filename
|
|
//
|
|
for (Index = 0; Index < HandleCount; Index++) {
|
|
|
|
Status = gBS->HandleProtocol (
|
|
HandleBuffer[Index],
|
|
&gEfiFirmwareVolume2ProtocolGuid,
|
|
(VOID **) &Fv
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
|
|
Size = 0;
|
|
Status = Fv->ReadFile (
|
|
Fv,
|
|
NameGuid,
|
|
NULL,
|
|
&Size,
|
|
&Type,
|
|
&Attributes,
|
|
&AuthenticationStatus
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// Skip if no specifie file in the fv
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Get fv device path
|
|
//
|
|
FileDevicePath = DevicePathFromHandle (HandleBuffer[Index]);
|
|
|
|
//
|
|
// Get the device path of the efi with file guid
|
|
//
|
|
EfiInitializeFwVolDevicepathNode (&FwVolFilePathNode, NameGuid);
|
|
|
|
//
|
|
// Append efi device path to fv device path
|
|
//
|
|
FileDevicePath = AppendDevicePathNode (
|
|
FileDevicePath,
|
|
(EFI_DEVICE_PATH_PROTOCOL *) &FwVolFilePathNode
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
FreePool (HandleBuffer);
|
|
|
|
if (FileDevicePath == NULL) {
|
|
//
|
|
// Cannot to find efi driver from fv
|
|
//
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Status = gBS->LoadImage (
|
|
FALSE,
|
|
gImageHandle,
|
|
FileDevicePath,
|
|
NULL,
|
|
0,
|
|
&ImageHandle
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (FileDevicePath);
|
|
return Status;
|
|
}
|
|
|
|
Status = BdsServices->CreateLoadOption (
|
|
BdsServices,
|
|
BOOT_OPTION,
|
|
NULL, // OptionName
|
|
NULL, // OptionGuid
|
|
LOAD_OPTION_ACTIVE,
|
|
FileDevicePath,
|
|
NULL, // Description
|
|
(UINT8 *) OsRecoveryOptionalData,
|
|
(UINT32) 0,
|
|
&BdsLoadOption
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (FileDevicePath);
|
|
return Status;
|
|
}
|
|
|
|
Status = BdsServices->LaunchLoadOption (
|
|
BdsServices,
|
|
BdsLoadOption,
|
|
&ExitDataSize,
|
|
&ExitData
|
|
);
|
|
|
|
FreePool (FileDevicePath);
|
|
FreePool (BdsLoadOption);
|
|
|
|
return Status;
|
|
}
|