/** @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 - 2010, Intel Corporation<BR>
  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 <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 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 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_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
                            );
        }
      }
    }
    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);
          Status = EFI_OUT_OF_RESOURCES;
          goto Finish;
        }
        //
        // 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 (!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) && (FileInfo != NULL)) {
            //
            // 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);
        }
        FreePool (TempDevicePathNode);
      }
    }
    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
                                 );
          }
        }
      }
      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;
}
