diff options
Diffstat (limited to 'MdePkg/Library/DxeServicesLib/DxeServicesLib.c')
-rw-r--r-- | MdePkg/Library/DxeServicesLib/DxeServicesLib.c | 929 |
1 files changed, 0 insertions, 929 deletions
diff --git a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c deleted file mode 100644 index c8f0014d7a..0000000000 --- a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c +++ /dev/null @@ -1,929 +0,0 @@ -/** @file
- MDE DXE Services Library provides functions that simplify the development of DXE Drivers.
- These functions help access data from sections of FFS files or from file path.
-
- Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
- 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 <PiDxe.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiLib.h>
-#include <Library/DxeServicesLib.h>
-#include <Protocol/FirmwareVolume2.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
- GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL
- protocol instance should be located succesfully by calling gBS->HandleProtocol ().
-
- This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed
- on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.
-
- If ImageHandle is NULL, then ASSERT ();
- If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();
-
- @param ImageHandle The firmware allocated handle for UEFI image.
-
- @retval EFI_HANDLE The device handle from which the Image is loaded from.
-
-**/
-EFI_HANDLE
-InternalImageHandleToFvHandle (
- EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
-
- ASSERT (ImageHandle != NULL);
-
- Status = gBS->HandleProtocol (
- (EFI_HANDLE *) ImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **) &LoadedImage
- );
-
- ASSERT_EFI_ERROR (Status);
-
- return LoadedImage->DeviceHandle;
-
-}
-
-/**
- Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware
- Section type and instance number from the specified Firmware Volume.
-
- This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to
- carry out the Firmware Volume read operation. The function then reads the Firmware Section found sepcifed
- by NameGuid, SectionType and SectionInstance.
-
- The details of this search order is defined in description of EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection ()
- found in PI Specification.
-
- If SectionType is EFI_SECTION_TE, EFI_SECTION_TE is used as section type to start the search. If EFI_SECTION_TE section
- is not found, EFI_SECTION_PE32 will be used to try the search again. If no EFI_SECTION_PE32 section is found, EFI_NOT_FOUND
- is returned.
-
- The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
- by this function. This function can be only called at TPL_NOTIFY and below.
-
- If FvHandle is NULL, then ASSERT ();
- If NameGuid is NULL, then ASSERT();
- If Buffer is NULL, then ASSERT();
- If Size is NULL, then ASSERT().
-
- @param FvHandle The device handle that contains a instance of
- EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
- @param NameGuid The GUID name of a Firmware File.
- @param SectionType The Firmware Section type.
- @param SectionInstance The instance number of Firmware Section to
- read from starting from 0.
- @param Buffer On output, Buffer contains the the data read
- from the section in the Firmware File found.
- @param Size On output, the size of Buffer.
-
- @retval EFI_SUCCESS The image is found and data and size is returned.
- @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType
- can't be found.
- @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the
- output data buffer or complete the operations.
- @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the
- Firmware Volume.
- @retval EFI_ACCESS_DENIED The firmware volume containing the searched
- Firmware File is configured to disallow reads.
-
-**/
-EFI_STATUS
-InternalGetSectionFromFv (
- IN EFI_HANDLE FvHandle,
- IN CONST EFI_GUID *NameGuid,
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN SectionInstance,
- OUT VOID **Buffer,
- OUT UINTN *Size
- )
-{
- EFI_STATUS Status;
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
- UINT32 AuthenticationStatus;
-
- ASSERT (NameGuid != NULL);
- ASSERT (Buffer != NULL);
- ASSERT (Size != NULL);
-
- ASSERT (FvHandle != NULL);
-
- Status = gBS->HandleProtocol (
- FvHandle,
- &gEfiFirmwareVolume2ProtocolGuid,
- (VOID **) &Fv
- );
- if (EFI_ERROR (Status)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Read desired section content in NameGuid file
- //
- *Buffer = NULL;
- *Size = 0;
- Status = Fv->ReadSection (
- Fv,
- NameGuid,
- SectionType,
- SectionInstance,
- Buffer,
- Size,
- &AuthenticationStatus
- );
-
- if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
- //
- // Try reading PE32 section, if the required section is TE type
- //
- *Buffer = NULL;
- *Size = 0;
- Status = Fv->ReadSection (
- Fv,
- NameGuid,
- EFI_SECTION_PE32,
- SectionInstance,
- Buffer,
- Size,
- &AuthenticationStatus
- );
- }
-
- return Status;
-}
-
-/**
- Searches all the available firmware volumes and returns the first matching FFS section.
-
- This function searches all the firmware volumes for FFS files with FV file type specified by FileType
- The order that the firmware volumes is searched is not deterministic. For each available FV a search
- is made for FFS file of type FileType. If the FV contains more than one FFS file with the same FileType,
- the FileInstance instance will be the matched FFS file. For each FFS file found a search
- is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances
- of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.
- Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.
- It is the caller's responsibility to use FreePool() to free the allocated buffer.
- See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections
- are retrieved from an FFS file based on SectionType and SectionInstance.
-
- If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
- the search will be retried with a section type of EFI_SECTION_PE32.
- This function must be called with a TPL <= TPL_NOTIFY.
-
- If Buffer is NULL, then ASSERT().
- If Size is NULL, then ASSERT().
-
- @param FileType Indicates the FV file type to search for within all
- available FVs.
- @param FileInstance Indicates which file instance within all available
- FVs specified by FileType.
- FileInstance starts from zero.
- @param SectionType Indicates the FFS section type to search for
- within the FFS file
- specified by FileType with FileInstance.
- @param SectionInstance Indicates which section instance within the FFS file
- specified by FileType with FileInstance to retrieve.
- SectionInstance starts from zero.
- @param Buffer On output, a pointer to a callee allocated buffer
- containing the FFS file section that was found.
- Is it the caller's responsibility to free this
- buffer using FreePool().
- @param Size On output, a pointer to the size, in bytes, of Buffer.
-
- @retval EFI_SUCCESS The specified FFS section was returned.
- @retval EFI_NOT_FOUND The specified FFS section could not be found.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve
- the matching FFS section.
- @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
- device error.
- @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because
- the firmware volume that
- contains the matching FFS section does not allow reads.
-**/
-EFI_STATUS
-EFIAPI
-GetSectionFromAnyFvByFileType (
- IN EFI_FV_FILETYPE FileType,
- IN UINTN FileInstance,
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN SectionInstance,
- OUT VOID **Buffer,
- OUT UINTN *Size
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- UINTN IndexFv;
- UINTN IndexFile;
- UINTN Key;
- EFI_GUID NameGuid;
- EFI_FV_FILE_ATTRIBUTES Attributes;
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
-
- //
- // Locate all available FVs.
- //
- HandleBuffer = NULL;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiFirmwareVolume2ProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Go through FVs one by one to find the required section data.
- //
- for (IndexFv = 0; IndexFv < HandleCount; IndexFv++) {
- Status = gBS->HandleProtocol (
- HandleBuffer[IndexFv],
- &gEfiFirmwareVolume2ProtocolGuid,
- (VOID **)&Fv
- );
- if (EFI_ERROR (Status)) {
- continue;
- }
-
- //
- // Use Firmware Volume 2 Protocol to search for a file of type FileType in all FVs.
- //
- IndexFile = FileInstance + 1;
- Key = 0;
- do {
- Status = Fv->GetNextFile (Fv, &Key, &FileType, &NameGuid, &Attributes, Size);
- if (EFI_ERROR (Status)) {
- break;
- }
- IndexFile --;
- } while (IndexFile > 0);
-
- //
- // Fv File with the required FV file type is found.
- // Search the section file in the found FV file.
- //
- if (IndexFile == 0) {
- Status = InternalGetSectionFromFv (
- HandleBuffer[IndexFv],
- &NameGuid,
- SectionType,
- SectionInstance,
- Buffer,
- Size
- );
-
- if (!EFI_ERROR (Status)) {
- goto Done;
- }
- }
- }
-
- //
- // The required FFS section file is not found.
- //
- if (IndexFv == HandleCount) {
- Status = EFI_NOT_FOUND;
- }
-
-Done:
- if (HandleBuffer != NULL) {
- FreePool(HandleBuffer);
- }
-
- return Status;
-}
-
-/**
- Searches all the availables firmware volumes and returns the first matching FFS section.
-
- This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.
- The order that the firmware volumes is searched is not deterministic. For each FFS file found a search
- is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances
- of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.
- Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.
- It is the caller's responsibility to use FreePool() to free the allocated buffer.
- See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections
- are retrieved from an FFS file based on SectionType and SectionInstance.
-
- If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
- the search will be retried with a section type of EFI_SECTION_PE32.
- This function must be called with a TPL <= TPL_NOTIFY.
-
- If NameGuid is NULL, then ASSERT().
- If Buffer is NULL, then ASSERT().
- If Size is NULL, then ASSERT().
-
-
- @param NameGuid A pointer to to the FFS filename GUID to search for
- within any of the firmware volumes in the platform.
- @param SectionType Indicates the FFS section type to search for within
- the FFS file specified by NameGuid.
- @param SectionInstance Indicates which section instance within the FFS file
- specified by NameGuid to retrieve.
- @param Buffer On output, a pointer to a callee allocated buffer
- containing the FFS file section that was found.
- Is it the caller's responsibility to free this buffer
- using FreePool().
- @param Size On output, a pointer to the size, in bytes, of Buffer.
-
- @retval EFI_SUCCESS The specified FFS section was returned.
- @retval EFI_NOT_FOUND The specified FFS section could not be found.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
- retrieve the matching FFS section.
- @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
- device error.
- @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the
- firmware volume that
- contains the matching FFS section does not allow reads.
-**/
-EFI_STATUS
-EFIAPI
-GetSectionFromAnyFv (
- IN CONST EFI_GUID *NameGuid,
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN SectionInstance,
- OUT VOID **Buffer,
- OUT UINTN *Size
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- UINTN Index;
- EFI_HANDLE FvHandle;
-
- //
- // Search the FV that contain the caller's FFS first.
- // FV builder can choose to build FFS into the this FV
- // so that this implementation of GetSectionFromAnyFv
- // will locate the FFS faster.
- //
- FvHandle = InternalImageHandleToFvHandle (gImageHandle);
- Status = InternalGetSectionFromFv (
- FvHandle,
- NameGuid,
- SectionType,
- SectionInstance,
- Buffer,
- Size
- );
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
- }
-
- HandleBuffer = NULL;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiFirmwareVolume2ProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- //
- // Skip the FV that contain the caller's FFS
- //
- if (HandleBuffer[Index] != FvHandle) {
- Status = InternalGetSectionFromFv (
- HandleBuffer[Index],
- NameGuid,
- SectionType,
- SectionInstance,
- Buffer,
- Size
- );
-
- if (!EFI_ERROR (Status)) {
- goto Done;
- }
- }
-
- }
-
- if (Index == HandleCount) {
- Status = EFI_NOT_FOUND;
- }
-
-Done:
-
- if (HandleBuffer != NULL) {
- FreePool(HandleBuffer);
- }
- return Status;
-
-}
-
-/**
- Searches the firmware volume that the currently executing module was loaded from and returns the first matching FFS section.
-
- This function searches the firmware volume that the currently executing module was loaded
- from for an FFS file with an FFS filename specified by NameGuid. If the FFS file is found a search
- is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance
- instances of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.
- Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.
- It is the caller's responsibility to use FreePool() to free the allocated buffer.
- See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from
- an FFS file based on SectionType and SectionInstance.
-
- If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned.
- If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
- the search will be retried with a section type of EFI_SECTION_PE32.
-
- This function must be called with a TPL <= TPL_NOTIFY.
- If NameGuid is NULL, then ASSERT().
- If Buffer is NULL, then ASSERT().
- If Size is NULL, then ASSERT().
-
- @param NameGuid A pointer to to the FFS filename GUID to search for
- within the firmware volumes that the currently
- executing module was loaded from.
- @param SectionType Indicates the FFS section type to search for within
- the FFS file specified by NameGuid.
- @param SectionInstance Indicates which section instance within the FFS file
- specified by NameGuid to retrieve.
- @param Buffer On output, a pointer to a callee allocated buffer
- containing the FFS file section that was found.
- Is it the caller's responsibility to free this buffer
- using FreePool().
- @param Size On output, a pointer to the size, in bytes, of Buffer.
-
-
- @retval EFI_SUCCESS The specified FFS section was returned.
- @retval EFI_NOT_FOUND The specified FFS section could not be found.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve
- the matching FFS section.
- @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
- device error.
- @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the
- firmware volume that contains the matching FFS
- section does not allow reads.
-**/
-EFI_STATUS
-EFIAPI
-GetSectionFromFv (
- IN CONST EFI_GUID *NameGuid,
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN SectionInstance,
- OUT VOID **Buffer,
- OUT UINTN *Size
- )
-{
- return InternalGetSectionFromFv (
- InternalImageHandleToFvHandle(gImageHandle),
- NameGuid,
- SectionType,
- SectionInstance,
- Buffer,
- Size
- );
-}
-
-
-/**
- Searches the FFS file the the currently executing module was loaded from and returns the first matching FFS section.
-
- This function searches the FFS file that the currently executing module was loaded from for a FFS sections of type SectionType.
- If the FFS file contains at least SectionInstance instances of the FFS section specified by SectionType,
- then the SectionInstance instance is returned in Buffer. Buffer is allocated using AllocatePool(),
- and the size of the allocated buffer is returned in Size. It is the caller's responsibility
- to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for
- details on how sections are retrieved from an FFS file based on SectionType and SectionInstance.
-
- If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned.
- If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
- the search will be retried with a section type of EFI_SECTION_PE32.
- This function must be called with a TPL <= TPL_NOTIFY.
-
- If Buffer is NULL, then ASSERT().
- If Size is NULL, then ASSERT().
-
-
- @param SectionType Indicates the FFS section type to search for within
- the FFS file that the currently executing module
- was loaded from.
- @param SectionInstance Indicates which section instance to retrieve within
- the FFS file that the currently executing module
- was loaded from.
- @param Buffer On output, a pointer to a callee allocated buffer
- containing the FFS file section that was found.
- Is it the caller's responsibility to free this buffer
- using FreePool().
- @param Size On output, a pointer to the size, in bytes, of Buffer.
-
- @retval EFI_SUCCESS The specified FFS section was returned.
- @retval EFI_NOT_FOUND The specified FFS section could not be found.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve
- the matching FFS section.
- @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a
- device error.
- @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the
- firmware volume that contains the matching FFS
- section does not allow reads.
-
-**/
-EFI_STATUS
-EFIAPI
-GetSectionFromFfs (
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN SectionInstance,
- OUT VOID **Buffer,
- OUT UINTN *Size
- )
-{
- return InternalGetSectionFromFv(
- InternalImageHandleToFvHandle(gImageHandle),
- &gEfiCallerIdGuid,
- SectionType,
- SectionInstance,
- Buffer,
- 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 FilePath 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 The pointer to the device path of the file
- that is absracted to the file buffer.
- @param[out] FileSize The pointer to the size of the abstracted
- file buffer.
- @param[out] AuthenticationStatus Pointer to the authentication status.
-
- @retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationStatus 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_DEVICE_PATH_PROTOCOL *TempDevicePathNode;
- 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
- //
- TempDevicePathNode = NULL;
- 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
- );
- }
- }
- }
- if (!EFI_ERROR (Status)) {
- 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)) {
- //
- // Duplicate the device path to avoid the access to unaligned device path node.
- // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH
- // nodes, It assures the fields in device path nodes are 2 byte aligned.
- //
- TempDevicePathNode = DuplicateDevicePath (DevicePathNode);
- if (TempDevicePathNode == NULL) {
- FileHandle->Close (FileHandle);
- //
- // Setting Status to an EFI_ERROR value will cause the rest of
- // the file system support below to be skipped.
- //
- Status = EFI_OUT_OF_RESOURCES;
- }
- //
- // 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
- //
- DevicePathNode = TempDevicePathNode;
- while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {
- 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) && (FileInfo != NULL)) {
- if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {
- //
- // 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 and TempDevicePathNode since we are done
- //
- if (FileInfo != NULL) {
- FreePool (FileInfo);
- }
- if (FileHandle != NULL) {
- FileHandle->Close (FileHandle);
- }
- if (TempDevicePathNode != NULL) {
- FreePool (TempDevicePathNode);
- }
- }
- }
- if (!EFI_ERROR (Status)) {
- 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,
- FALSE,
- &ImageBufferSize,
- ImageBuffer
- );
- }
- }
- }
- if (!EFI_ERROR (Status)) {
- 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;
-}
|