Add new GetFileBufferByFilePath API into DxeServicesLib.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9486 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
2474e48aa7
commit
847166140a
|
@ -1,8 +1,8 @@
|
||||||
/** @file
|
/** @file
|
||||||
MDE DXE Services Library provides functions that simplify the development of DXE Drivers.
|
MDE DXE Services Library provides functions that simplify the development of DXE Drivers.
|
||||||
These functions help access data from sections of FFS files.
|
These functions help access data from sections of FFS files or from file path.
|
||||||
|
|
||||||
Copyright (c) 2008, Intel Corporation<BR>
|
Copyright (c) 2008 - 2009, Intel Corporation<BR>
|
||||||
All rights reserved. This program and the accompanying materials
|
All rights reserved. This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -154,5 +154,41 @@ GetSectionFromFfs (
|
||||||
OUT UINTN *Size
|
OUT UINTN *Size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the image file buffer data and buffer size by its device path.
|
||||||
|
|
||||||
|
Access the file either from a firmware volume, from a file system interface,
|
||||||
|
or from the load file interface.
|
||||||
|
|
||||||
|
Allocate memory to store the found image. The caller is responsible to free memory.
|
||||||
|
|
||||||
|
If File is NULL, then NULL is returned.
|
||||||
|
If FileSize is NULL, then NULL is returned.
|
||||||
|
If AuthenticationStatus is NULL, then NULL is returned.
|
||||||
|
|
||||||
|
@param[in] BootPolicy
|
||||||
|
Policy for Open Image File.If TRUE, indicates that the request
|
||||||
|
originates from the boot manager, and that the boot manager is
|
||||||
|
attempting to load FilePath as a boot selection. If FALSE,
|
||||||
|
then FilePath must match an exact file to be loaded.
|
||||||
|
@param[in] File Pointer to the device path of the file that is absracted to the file buffer.
|
||||||
|
@param[out] FileSize Pointer to the size of the abstracted file buffer.
|
||||||
|
@param[out] AuthenticationStatus
|
||||||
|
Pointer to a caller-allocated UINT32 in which
|
||||||
|
the authentication status is returned.
|
||||||
|
|
||||||
|
@retval NULL File is NULL, or FileSize is NULL. Or the file can't be found.
|
||||||
|
@retval other The abstracted file buffer. The caller is responsible to free memory.
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
GetFileBufferByFilePath (
|
||||||
|
IN BOOLEAN BootPolicy,
|
||||||
|
IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||||
|
OUT UINTN *FileSize,
|
||||||
|
OUT UINT32 *AuthenticationStatus
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/** @file
|
/** @file
|
||||||
MDE DXE Services Library provides functions that simplify the development of DXE Drivers.
|
MDE DXE Services Library provides functions that simplify the development of DXE Drivers.
|
||||||
These functions help access data from sections of FFS files.
|
These functions help access data from sections of FFS files or from file path.
|
||||||
|
|
||||||
Copyright (c) 2007 - 2008, Intel Corporation<BR>
|
Copyright (c) 2007 - 2009, Intel Corporation<BR>
|
||||||
All rights reserved. This program and the accompanying materials
|
All rights reserved. This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -17,10 +17,15 @@
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/DevicePathLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/DxeServicesLib.h>
|
#include <Library/DxeServicesLib.h>
|
||||||
#include <Protocol/FirmwareVolume2.h>
|
#include <Protocol/FirmwareVolume2.h>
|
||||||
#include <Protocol/LoadedImage.h>
|
#include <Protocol/LoadedImage.h>
|
||||||
|
#include <Protocol/LoadFile2.h>
|
||||||
|
#include <Protocol/LoadFile.h>
|
||||||
|
#include <Protocol/SimpleFileSystem.h>
|
||||||
|
#include <Guid/FileInfo.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Identify the device handle from which the Image is loaded from. As this device handle is passed to
|
Identify the device handle from which the Image is loaded from. As this device handle is passed to
|
||||||
|
@ -392,3 +397,332 @@ GetSectionFromFfs (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the image file buffer data and buffer size by its device path.
|
||||||
|
|
||||||
|
Access the file either from a a firmware volume, from a file system interface,
|
||||||
|
or from the load file interface.
|
||||||
|
|
||||||
|
Allocate memory to store the found image. The caller is responsible to free memory.
|
||||||
|
|
||||||
|
If File is NULL, then NULL is returned.
|
||||||
|
If FileSize is NULL, then NULL is returned.
|
||||||
|
If AuthenticationStatus is NULL, then NULL is returned.
|
||||||
|
|
||||||
|
@param[in] BootPolicy
|
||||||
|
Policy for Open Image File.If TRUE, indicates that the request
|
||||||
|
originates from the boot manager, and that the boot manager is
|
||||||
|
attempting to load FilePath as a boot selection. If FALSE,
|
||||||
|
then FilePath must match an exact file to be loaded.
|
||||||
|
@param[in] FilePath Pointer to the device path of the file that is absracted to the file buffer.
|
||||||
|
@param[out] FileSize Pointer to the size of the abstracted file buffer.
|
||||||
|
@param[out] AuthenticationStatus
|
||||||
|
Pointer to a caller-allocated UINT32 in which
|
||||||
|
the authentication status is returned.
|
||||||
|
|
||||||
|
@retval NULL File is NULL, or FileSize is NULL. Or the file can't be found.
|
||||||
|
@retval other The abstracted file buffer. The caller is responsible to free memory.
|
||||||
|
**/
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
GetFileBufferByFilePath (
|
||||||
|
IN BOOLEAN BootPolicy,
|
||||||
|
IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||||
|
OUT UINTN *FileSize,
|
||||||
|
OUT UINT32 *AuthenticationStatus
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
|
||||||
|
EFI_HANDLE Handle;
|
||||||
|
EFI_GUID *FvNameGuid;
|
||||||
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
|
||||||
|
EFI_SECTION_TYPE SectionType;
|
||||||
|
UINT8 *ImageBuffer;
|
||||||
|
UINTN ImageBufferSize;
|
||||||
|
EFI_FV_FILETYPE Type;
|
||||||
|
EFI_FV_FILE_ATTRIBUTES Attrib;
|
||||||
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
|
||||||
|
EFI_FILE_HANDLE FileHandle;
|
||||||
|
EFI_FILE_HANDLE LastHandle;
|
||||||
|
EFI_FILE_INFO *FileInfo;
|
||||||
|
UINTN FileInfoSize;
|
||||||
|
EFI_LOAD_FILE_PROTOCOL *LoadFile;
|
||||||
|
EFI_LOAD_FILE2_PROTOCOL *LoadFile2;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check input File device path.
|
||||||
|
//
|
||||||
|
if (FilePath == NULL || FileSize == NULL || AuthenticationStatus == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init local variable
|
||||||
|
//
|
||||||
|
FvNameGuid = NULL;
|
||||||
|
FileInfo = NULL;
|
||||||
|
FileHandle = NULL;
|
||||||
|
ImageBuffer = NULL;
|
||||||
|
ImageBufferSize = 0;
|
||||||
|
*AuthenticationStatus = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy File Device Path
|
||||||
|
//
|
||||||
|
OrigDevicePathNode = DuplicateDevicePath (FilePath);
|
||||||
|
if (OrigDevicePathNode == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check whether this device path support FV2 protocol.
|
||||||
|
// Is so, this device path may contain a Image.
|
||||||
|
//
|
||||||
|
DevicePathNode = OrigDevicePathNode;
|
||||||
|
Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// For FwVol File system there is only a single file name that is a GUID.
|
||||||
|
//
|
||||||
|
FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePathNode);
|
||||||
|
if (FvNameGuid == NULL) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Read image from the firmware file
|
||||||
|
//
|
||||||
|
Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
SectionType = EFI_SECTION_PE32;
|
||||||
|
ImageBuffer = NULL;
|
||||||
|
Status = FwVol->ReadSection (
|
||||||
|
FwVol,
|
||||||
|
FvNameGuid,
|
||||||
|
SectionType,
|
||||||
|
0,
|
||||||
|
(VOID **)&ImageBuffer,
|
||||||
|
&ImageBufferSize,
|
||||||
|
AuthenticationStatus
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Try a raw file, since a PE32 SECTION does not exist
|
||||||
|
//
|
||||||
|
if (ImageBuffer != NULL) {
|
||||||
|
FreePool (ImageBuffer);
|
||||||
|
*AuthenticationStatus = 0;
|
||||||
|
}
|
||||||
|
ImageBuffer = NULL;
|
||||||
|
Status = FwVol->ReadFile (
|
||||||
|
FwVol,
|
||||||
|
FvNameGuid,
|
||||||
|
(VOID **)&ImageBuffer,
|
||||||
|
&ImageBufferSize,
|
||||||
|
&Type,
|
||||||
|
&Attrib,
|
||||||
|
AuthenticationStatus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Attempt to access the file via a file system interface
|
||||||
|
//
|
||||||
|
DevicePathNode = OrigDevicePathNode;
|
||||||
|
Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Open the Volume to get the File System handle
|
||||||
|
//
|
||||||
|
Status = Volume->OpenVolume (Volume, &FileHandle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
|
||||||
|
// directory information and filename can be seperate. The goal is to inch
|
||||||
|
// our way down each device path node and close the previous node
|
||||||
|
//
|
||||||
|
while (!IsDevicePathEnd (DevicePathNode) && !EFI_ERROR (Status)) {
|
||||||
|
if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||
|
||||||
|
DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastHandle = FileHandle;
|
||||||
|
FileHandle = NULL;
|
||||||
|
|
||||||
|
Status = LastHandle->Open (
|
||||||
|
LastHandle,
|
||||||
|
&FileHandle,
|
||||||
|
((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,
|
||||||
|
EFI_FILE_MODE_READ,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close the previous node
|
||||||
|
//
|
||||||
|
LastHandle->Close (LastHandle);
|
||||||
|
|
||||||
|
DevicePathNode = NextDevicePathNode (DevicePathNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// We have found the file. Now we need to read it. Before we can read the file we need to
|
||||||
|
// figure out how big the file is.
|
||||||
|
//
|
||||||
|
FileInfo = NULL;
|
||||||
|
FileInfoSize = 0;
|
||||||
|
Status = FileHandle->GetInfo (
|
||||||
|
FileHandle,
|
||||||
|
&gEfiFileInfoGuid,
|
||||||
|
&FileInfoSize,
|
||||||
|
FileInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
FileInfo = AllocatePool (FileInfoSize);
|
||||||
|
if (FileInfo == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
} else {
|
||||||
|
Status = FileHandle->GetInfo (
|
||||||
|
FileHandle,
|
||||||
|
&gEfiFileInfoGuid,
|
||||||
|
&FileInfoSize,
|
||||||
|
FileInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Allocate space for the file
|
||||||
|
//
|
||||||
|
ImageBuffer = AllocatePool ((UINTN)FileInfo->FileSize);
|
||||||
|
if (ImageBuffer == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Read the file into the buffer we allocated
|
||||||
|
//
|
||||||
|
ImageBufferSize = (UINTN)FileInfo->FileSize;
|
||||||
|
Status = FileHandle->Read (FileHandle, &ImageBufferSize, ImageBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Close the file and Free FileInfo since we are done
|
||||||
|
//
|
||||||
|
if (FileInfo != NULL) {
|
||||||
|
FreePool (FileInfo);
|
||||||
|
}
|
||||||
|
if (FileHandle != NULL) {
|
||||||
|
FileHandle->Close (FileHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Attempt to access the file via LoadFile2 interface
|
||||||
|
//
|
||||||
|
if (!BootPolicy) {
|
||||||
|
DevicePathNode = OrigDevicePathNode;
|
||||||
|
Status = gBS->LocateDevicePath (&gEfiLoadFile2ProtocolGuid, &DevicePathNode, &Handle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->HandleProtocol (Handle, &gEfiLoadFile2ProtocolGuid, (VOID**)&LoadFile2);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Call LoadFile2 with the correct buffer size
|
||||||
|
//
|
||||||
|
ImageBufferSize = 0;
|
||||||
|
ImageBuffer = NULL;
|
||||||
|
Status = LoadFile2->LoadFile (
|
||||||
|
LoadFile2,
|
||||||
|
DevicePathNode,
|
||||||
|
FALSE,
|
||||||
|
&ImageBufferSize,
|
||||||
|
ImageBuffer
|
||||||
|
);
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
ImageBuffer = AllocatePool (ImageBufferSize);
|
||||||
|
if (ImageBuffer == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
} else {
|
||||||
|
Status = LoadFile2->LoadFile (
|
||||||
|
LoadFile2,
|
||||||
|
DevicePathNode,
|
||||||
|
BootPolicy,
|
||||||
|
&ImageBufferSize,
|
||||||
|
ImageBuffer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Attempt to access the file via LoadFile interface
|
||||||
|
//
|
||||||
|
DevicePathNode = OrigDevicePathNode;
|
||||||
|
Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePathNode, &Handle);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID**)&LoadFile);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Call LoadFile with the correct buffer size
|
||||||
|
//
|
||||||
|
ImageBufferSize = 0;
|
||||||
|
ImageBuffer = NULL;
|
||||||
|
Status = LoadFile->LoadFile (
|
||||||
|
LoadFile,
|
||||||
|
DevicePathNode,
|
||||||
|
BootPolicy,
|
||||||
|
&ImageBufferSize,
|
||||||
|
ImageBuffer
|
||||||
|
);
|
||||||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
ImageBuffer = AllocatePool (ImageBufferSize);
|
||||||
|
if (ImageBuffer == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
} else {
|
||||||
|
Status = LoadFile->LoadFile (
|
||||||
|
LoadFile,
|
||||||
|
DevicePathNode,
|
||||||
|
BootPolicy,
|
||||||
|
&ImageBufferSize,
|
||||||
|
ImageBuffer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Finish:
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
if (ImageBuffer != NULL) {
|
||||||
|
FreePool (ImageBuffer);
|
||||||
|
ImageBuffer = NULL;
|
||||||
|
}
|
||||||
|
*FileSize = 0;
|
||||||
|
} else {
|
||||||
|
*FileSize = ImageBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (OrigDevicePathNode);
|
||||||
|
|
||||||
|
return ImageBuffer;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#/** @file
|
#/** @file
|
||||||
# DXE Services Library provides access data from sections of FFS files based on FV protocol.
|
# DXE Services Library provides access data from sections of FFS files based on FV protocol.
|
||||||
|
# It also provides access file based on file path from a firmware volume,
|
||||||
|
# from a file system interface, or from the load file interface.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2007 - 2008, Intel Corporation.
|
# Copyright (c) 2007 - 2009, Intel Corporation.
|
||||||
#
|
#
|
||||||
# All rights reserved. This program and the accompanying materials
|
# All rights reserved. This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -36,9 +38,16 @@
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
DebugLib
|
DebugLib
|
||||||
|
DevicePathLib
|
||||||
|
UefiLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEfiFileInfoGuid ## CONSUMES
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
|
gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
|
||||||
gEfiLoadedImageProtocolGuid ## CONSUMES
|
gEfiLoadedImageProtocolGuid ## CONSUMES
|
||||||
|
gEfiLoadFileProtocolGuid ## CONSUMES
|
||||||
|
gEfiLoadFile2ProtocolGuid ## CONSUMES
|
||||||
|
gEfiSimpleFileSystemProtocolGuid ## CONSUMES
|
||||||
|
|
Loading…
Reference in New Issue