summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Core/Dxe/Image
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Core/Dxe/Image')
-rw-r--r--EdkModulePkg/Core/Dxe/Image/Image.c1390
-rw-r--r--EdkModulePkg/Core/Dxe/Image/ImageFile.c499
2 files changed, 0 insertions, 1889 deletions
diff --git a/EdkModulePkg/Core/Dxe/Image/Image.c b/EdkModulePkg/Core/Dxe/Image/Image.c
deleted file mode 100644
index 341df42614..0000000000
--- a/EdkModulePkg/Core/Dxe/Image/Image.c
+++ /dev/null
@@ -1,1390 +0,0 @@
-/*++
-
-Copyright (c) 2006 - 2007, Intel Corporation
-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.
-
-Module Name:
-
- Image.c
-
-Abstract:
-
- Core image handling services
-
---*/
-
-#include <DxeMain.h>
-//
-// Module Globals
-//
-
-LOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL;
-
-LOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = {
- LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE,
- NULL,
- {
- CoreLoadImageEx,
- CoreUnloadImageEx
- }
-};
-
-
-//
-// This code is needed to build the Image handle for the DXE Core
-//
-LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = {
- LOADED_IMAGE_PRIVATE_DATA_SIGNATURE, // Signature
- NULL, // Image handle
- EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, // Image type
- TRUE, // If entrypoint has been called
- NULL, // EntryPoint
- {
- EFI_LOADED_IMAGE_INFORMATION_REVISION, // Revision
- NULL, // Parent handle
- NULL, // System handle
-
- NULL, // Device handle
- NULL, // File path
- NULL, // Reserved
-
- 0, // LoadOptionsSize
- NULL, // LoadOptions
-
- NULL, // ImageBase
- 0, // ImageSize
- EfiBootServicesCode, // ImageCodeType
- EfiBootServicesData // ImageDataType
- },
- (EFI_PHYSICAL_ADDRESS)0, // ImageBasePage
- 0, // NumberOfPages
- NULL, // FixupData
- 0, // Tpl
- EFI_SUCCESS, // Status
- 0, // ExitDataSize
- NULL, // ExitData
- NULL, // JumpBuffer
- NULL, // JumpContext
- 0, // Machine
- NULL, // Ebc
- NULL, // RuntimeData
-};
-
-
-EFI_STATUS
-CoreInitializeImageServices (
- IN VOID *HobStart
- )
-/*++
-
-Routine Description:
-
- Add the Image Services to EFI Boot Services Table and install the protocol
- interfaces for this image.
-
-Arguments:
-
- HobStart - The HOB to initialize
-
-Returns:
-
- Status code.
-
---*/
-{
- EFI_STATUS Status;
- LOADED_IMAGE_PRIVATE_DATA *Image;
- EFI_PHYSICAL_ADDRESS DxeCoreImageBaseAddress;
- UINT64 DxeCoreImageLength;
- VOID *DxeCoreEntryPoint;
- EFI_PEI_HOB_POINTERS DxeCoreHob;
- //
- // Searching for image hob
- //
- DxeCoreHob.Raw = HobStart;
- while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) {
- if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
- //
- // Find Dxe Core HOB
- //
- break;
- }
- DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob);
- }
- ASSERT (DxeCoreHob.Raw != NULL);
-
- DxeCoreImageBaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
- DxeCoreImageLength = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength;
- DxeCoreEntryPoint = (VOID *) (UINTN) DxeCoreHob.MemoryAllocationModule->EntryPoint;
- gDxeCoreFileName = &DxeCoreHob.MemoryAllocationModule->ModuleName;
- //
- // Initialize the fields for an internal driver
- //
- Image = &mCorePrivateImage;
-
- Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)DxeCoreEntryPoint;
- Image->ImageBasePage = DxeCoreImageBaseAddress;
- Image->NumberOfPages = (UINTN)(EFI_SIZE_TO_PAGES((UINTN)(DxeCoreImageLength)));
- Image->Tpl = gEfiCurrentTpl;
- Image->Info.SystemTable = gDxeCoreST;
- Image->Info.ImageBase = (VOID *)(UINTN)DxeCoreImageBaseAddress;
- Image->Info.ImageSize = DxeCoreImageLength;
-
- //
- // Install the protocol interfaces for this image
- //
- Status = CoreInstallProtocolInterface (
- &Image->Handle,
- &gEfiLoadedImageProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &Image->Info
- );
- ASSERT_EFI_ERROR (Status);
-
- mCurrentImage = Image;
-
- //
- // Fill in DXE globals
- //
- gDxeCoreImageHandle = Image->Handle;
- gDxeCoreLoadedImage = &Image->Info;
-
- //
- // Export DXE Core PE Loader functionality
- //
- return CoreInstallProtocolInterface (
- &mLoadPe32PrivateData.Handle,
- &gEfiLoadPeImageProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mLoadPe32PrivateData.Pe32Image
- );
-}
-
-EFI_STATUS
-CoreLoadPeImage (
- IN VOID *Pe32Handle,
- IN LOADED_IMAGE_PRIVATE_DATA *Image,
- IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
- IN UINT32 Attribute
- )
-/*++
-
-Routine Description:
-
- Loads, relocates, and invokes a PE/COFF image
-
-Arguments:
-
- Pe32Handle - The handle of PE32 image
- Image - PE image to be loaded
- DstBuffer - The buffer to store the image
- EntryPoint - A pointer to the entry point
- Attribute - The bit mask of attributes to set for the load PE image
-
-Returns:
-
- EFI_SUCCESS - The file was loaded, relocated, and invoked
-
- EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
-
- EFI_INVALID_PARAMETER - Invalid parameter
-
- EFI_BUFFER_TOO_SMALL - Buffer for image is too small
-
---*/
-{
- EFI_STATUS Status;
- BOOLEAN DstBufAlocated;
- UINTN Size;
-
- ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext));
-
- Image->ImageContext.Handle = Pe32Handle;
- Image->ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)CoreReadImageFile;
-
- //
- // Get information about the image being loaded
- //
- Status = gEfiPeiPeCoffLoader->GetImageInfo (gEfiPeiPeCoffLoader, &Image->ImageContext);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine)) {
- //
- // The PE/COFF loader can support loading image types that can be executed.
- // If we loaded an image type that we can not execute return EFI_UNSUPORTED.
- //
- return EFI_UNSUPPORTED;
- }
-
-
- //
- // Allocate memory of the correct memory type aligned on the required image boundry
- //
- DstBufAlocated = FALSE;
- if (DstBuffer == 0) {
- //
- // Allocate Destination Buffer as caller did not pass it in
- //
-
- if (Image->ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
- Size = (UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment;
- } else {
- Size = (UINTN)Image->ImageContext.ImageSize;
- }
-
- Image->NumberOfPages = EFI_SIZE_TO_PAGES (Size);
-
- //
- // If the image relocations have not been stripped, then load at any address.
- // Otherwise load at the address at which it was linked.
- //
- // Memory below 1MB should be treated reserved for CSM and there should be
- // no modules whose preferred load addresses are below 1MB.
- //
- Status = EFI_OUT_OF_RESOURCES;
- if (Image->ImageContext.ImageAddress >= 0x100000 || Image->ImageContext.RelocationsStripped) {
- Status = CoreAllocatePages (
- AllocateAddress,
- (EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType),
- Image->NumberOfPages,
- &Image->ImageContext.ImageAddress
- );
- }
- if (EFI_ERROR (Status) && !Image->ImageContext.RelocationsStripped) {
- Status = CoreAllocatePages (
- AllocateAnyPages,
- (EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType),
- Image->NumberOfPages,
- &Image->ImageContext.ImageAddress
- );
- }
- if (EFI_ERROR (Status)) {
- return Status;
- }
- DstBufAlocated = TRUE;
- } else {
- //
- // Caller provided the destination buffer
- //
-
- if (Image->ImageContext.RelocationsStripped && (Image->ImageContext.ImageAddress != DstBuffer)) {
- //
- // If the image relocations were stripped, and the caller provided a
- // destination buffer address that does not match the address that the
- // image is linked at, then the image cannot be loaded.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- if (Image->NumberOfPages != 0 &&
- Image->NumberOfPages <
- (EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment))) {
- Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
- return EFI_BUFFER_TOO_SMALL;
- }
-
- Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
- Image->ImageContext.ImageAddress = DstBuffer;
- }
-
- Image->ImageBasePage = Image->ImageContext.ImageAddress;
- Image->ImageContext.ImageAddress =
- (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &
- ~((UINTN)Image->ImageContext.SectionAlignment - 1);
-
- //
- // Load the image from the file into the allocated memory
- //
- Status = gEfiPeiPeCoffLoader->LoadImage (gEfiPeiPeCoffLoader, &Image->ImageContext);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // If this is a Runtime Driver, then allocate memory for the FixupData that
- // is used to relocate the image when SetVirtualAddressMap() is called. The
- // relocation is done by the Runtime AP.
- //
- if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) {
- if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
- Image->ImageContext.FixupData = CoreAllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize));
- if (Image->ImageContext.FixupData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- }
- }
-
- //
- // Relocate the image in memory
- //
- Status = gEfiPeiPeCoffLoader->RelocateImage (gEfiPeiPeCoffLoader, &Image->ImageContext);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // Flush the Instruction Cache
- //
- InvalidateInstructionCacheRange ((VOID *)(UINTN)Image->ImageContext.ImageAddress, (UINTN)Image->ImageContext.ImageSize);
-
- //
- // Copy the machine type from the context to the image private data. This
- // is needed during image unload to know if we should call an EBC protocol
- // to unload the image.
- //
- Image->Machine = Image->ImageContext.Machine;
-
- //
- // Get the image entry point. If it's an EBC image, then call into the
- // interpreter to create a thunk for the entry point and use the returned
- // value for the entry point.
- //
- Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)Image->ImageContext.EntryPoint;
- if (Image->ImageContext.Machine == EFI_IMAGE_MACHINE_EBC) {
- //
- // Locate the EBC interpreter protocol
- //
- Status = CoreLocateProtocol (&gEfiEbcProtocolGuid, NULL, (VOID **)&Image->Ebc);
- if (EFI_ERROR(Status)) {
- goto Done;
- }
-
- //
- // Register a callback for flushing the instruction cache so that created
- // thunks can be flushed.
- //
- Status = Image->Ebc->RegisterICacheFlush (Image->Ebc, (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange);
- if (EFI_ERROR(Status)) {
- goto Done;
- }
-
- //
- // Create a thunk for the image's entry point. This will be the new
- // entry point for the image.
- //
- Status = Image->Ebc->CreateThunk (
- Image->Ebc,
- Image->Handle,
- (VOID *)(UINTN)Image->ImageContext.EntryPoint,
- (VOID **)&Image->EntryPoint
- );
- if (EFI_ERROR(Status)) {
- goto Done;
- }
- }
-
- //
- // Fill in the image information for the Loaded Image Protocol
- //
- Image->Type = Image->ImageContext.ImageType;
- Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageContext.ImageAddress;
- Image->Info.ImageSize = Image->ImageContext.ImageSize;
- Image->Info.ImageCodeType = (EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType);
- Image->Info.ImageDataType = (EFI_MEMORY_TYPE) (Image->ImageContext.ImageDataMemoryType);
- if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) {
- if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
- //
- // Make a list off all the RT images so we can let the RT AP know about them.
- //
- Image->RuntimeData = CoreAllocateRuntimePool (sizeof(EFI_RUNTIME_IMAGE_ENTRY));
- if (Image->RuntimeData == NULL) {
- goto Done;
- }
- Image->RuntimeData->ImageBase = Image->Info.ImageBase;
- Image->RuntimeData->ImageSize = (UINT64) (Image->Info.ImageSize);
- Image->RuntimeData->RelocationData = Image->ImageContext.FixupData;
- Image->RuntimeData->Handle = Image->Handle;
- InsertTailList (&gRuntime->ImageHead, &Image->RuntimeData->Link);
- }
- }
-
- //
- // Fill in the entry point of the image if it is available
- //
- if (EntryPoint != NULL) {
- *EntryPoint = Image->ImageContext.EntryPoint;
- }
-
- //
- // Print the load address and the PDB file name if it is available
- //
-
- DEBUG_CODE_BEGIN ();
-
- UINTN Index;
- UINTN StartIndex;
- CHAR8 EfiFileName[256];
-
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading driver at 0x%10p EntryPoint=0x%10p ", (VOID *)(UINTN)Image->ImageContext.ImageAddress, (VOID *)(UINTN)Image->ImageContext.EntryPoint));
- if (Image->ImageContext.PdbPointer != NULL) {
- StartIndex = 0;
- for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {
- if (Image->ImageContext.PdbPointer[Index] == '\\') {
- StartIndex = Index + 1;
- }
- }
- //
- // Copy the PDB file name to our temporary string, and replace .pdb with .efi
- //
- for (Index = 0; Index < sizeof (EfiFileName); Index++) {
- EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];
- if (EfiFileName[Index] == 0) {
- EfiFileName[Index] = '.';
- }
- if (EfiFileName[Index] == '.') {
- EfiFileName[Index + 1] = 'e';
- EfiFileName[Index + 2] = 'f';
- EfiFileName[Index + 3] = 'i';
- EfiFileName[Index + 4] = 0;
- break;
- }
- }
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
- }
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));
-
- DEBUG_CODE_END ();
-
- return EFI_SUCCESS;
-
-Done:
-
- //
- // Free memory.
- //
-
- if (DstBufAlocated) {
- CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages);
- }
-
- if (Image->ImageContext.FixupData != NULL) {
- CoreFreePool (Image->ImageContext.FixupData);
- }
-
- return Status;
-}
-
-
-LOADED_IMAGE_PRIVATE_DATA *
-CoreLoadedImageInfo (
- IN EFI_HANDLE ImageHandle
- )
-/*++
-
-Routine Description:
-
- Get the image's private data from its handle.
-
-Arguments:
-
- ImageHandle - The image handle
-
-Returns:
-
- Return the image private data associated with ImageHandle.
-
---*/
-{
- EFI_STATUS Status;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
- LOADED_IMAGE_PRIVATE_DATA *Image;
-
- Status = CoreHandleProtocol (
- ImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&LoadedImage
- );
- if (!EFI_ERROR (Status)) {
- Image = LOADED_IMAGE_PRIVATE_DATA_FROM_THIS (LoadedImage);
- } else {
- DEBUG ((EFI_D_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %x\n", ImageHandle));
- Image = NULL;
- }
-
- return Image;
-}
-
-STATIC
-EFI_STATUS
-CoreLoadImageCommon (
- IN BOOLEAN BootPolicy,
- IN EFI_HANDLE ParentImageHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- IN VOID *SourceBuffer OPTIONAL,
- IN UINTN SourceSize,
- IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
- IN OUT UINTN *NumberOfPages OPTIONAL,
- OUT EFI_HANDLE *ImageHandle,
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
- IN UINT32 Attribute
- )
-/*++
-
-Routine Description:
-
- Loads an EFI image into memory and returns a handle to the image.
-
-Arguments:
-
- BootPolicy - 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.
- ParentImageHandle - The caller's image handle.
- FilePath - The specific file path from which the image is loaded.
- SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
- the image to be loaded.
- SourceSize - The size in bytes of SourceBuffer.
- DstBuffer - The buffer to store the image
- NumberOfPages - If not NULL, a pointer to the image's page number, if this number
- is not enough, return EFI_BUFFER_TOO_SMALL and this parameter contain
- the required number.
- ImageHandle - Pointer to the returned image handle that is created when the image
- is successfully loaded.
- EntryPoint - A pointer to the entry point
- Attribute - The bit mask of attributes to set for the load PE image
-
-Returns:
-
- EFI_SUCCESS - The image was loaded into memory.
- EFI_NOT_FOUND - The FilePath was not found.
- EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
- EFI_BUFFER_TOO_SMALL - The buffer is too small
- EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
- parsed to locate the proper protocol for loading the file.
- EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
---*/
-{
- LOADED_IMAGE_PRIVATE_DATA *Image;
- LOADED_IMAGE_PRIVATE_DATA *ParentImage;
- IMAGE_FILE_HANDLE FHand;
- EFI_STATUS Status;
- EFI_STATUS SecurityStatus;
- EFI_HANDLE DeviceHandle;
- UINT32 AuthenticationStatus;
- EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
- EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
- UINTN FilePathSize;
-
- SecurityStatus = EFI_SUCCESS;
-
- ASSERT (gEfiCurrentTpl < TPL_NOTIFY);
- ParentImage = NULL;
-
- //
- // The caller must pass in a valid ParentImageHandle
- //
- if (ImageHandle == NULL || ParentImageHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ParentImage = CoreLoadedImageInfo (ParentImageHandle);
- if (ParentImage == NULL) {
- DEBUG((EFI_D_LOAD|EFI_D_ERROR, "LoadImageEx: Parent handle not an image handle\n"));
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Get simple read access to the source file
- //
- OriginalFilePath = FilePath;
- Status = CoreOpenImageFile (
- BootPolicy,
- SourceBuffer,
- SourceSize,
- FilePath,
- &DeviceHandle,
- &FHand,
- &AuthenticationStatus
- );
- if (Status == EFI_ALREADY_STARTED) {
- Image = NULL;
- goto Done;
- } else if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Verify the Authentication Status through the Security Architectural Protocol
- //
- if ((gSecurity != NULL) && (OriginalFilePath != NULL)) {
- SecurityStatus = gSecurity->FileAuthenticationState (
- gSecurity,
- AuthenticationStatus,
- OriginalFilePath
- );
- if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) {
- Status = SecurityStatus;
- Image = NULL;
- goto Done;
- }
- }
-
-
- //
- // Allocate a new image structure
- //
- Image = CoreAllocateZeroBootServicesPool (sizeof(LOADED_IMAGE_PRIVATE_DATA));
- if (Image == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Pull out just the file portion of the DevicePath for the LoadedImage FilePath
- //
- Status = CoreHandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
- if (!EFI_ERROR (Status)) {
- FilePathSize = CoreDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
- FilePath = (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *)FilePath) + FilePathSize );
- }
-
- //
- // Initialize the fields for an internal driver
- //
- Image->Signature = LOADED_IMAGE_PRIVATE_DATA_SIGNATURE;
- Image->Info.SystemTable = gDxeCoreST;
- Image->Info.DeviceHandle = DeviceHandle;
- Image->Info.Revision = EFI_LOADED_IMAGE_INFORMATION_REVISION;
- Image->Info.FilePath = CoreDuplicateDevicePath (FilePath);
- Image->Info.ParentHandle = ParentImageHandle;
-
- if (NumberOfPages != NULL) {
- Image->NumberOfPages = *NumberOfPages ;
- } else {
- Image->NumberOfPages = 0 ;
- }
-
- //
- // Install the protocol interfaces for this image
- // don't fire notifications yet
- //
- Status = CoreInstallProtocolInterfaceNotify (
- &Image->Handle,
- &gEfiLoadedImageProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &Image->Info,
- FALSE
- );
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
- //
- // Load the image. If EntryPoint is Null, it will not be set.
- //
- Status = CoreLoadPeImage (&FHand, Image, DstBuffer, EntryPoint, Attribute);
- if (EFI_ERROR (Status)) {
- if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_OUT_OF_RESOURCES)) {
- if (NumberOfPages != NULL) {
- *NumberOfPages = Image->NumberOfPages;
- }
- }
- goto Done;
- }
-
- //
- // Register the image in the Debug Image Info Table if the attribute is set
- //
- if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) {
- CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle);
- }
-
- //
- //Reinstall loaded image protocol to fire any notifications
- //
- Status = CoreReinstallProtocolInterface (
- Image->Handle,
- &gEfiLoadedImageProtocolGuid,
- &Image->Info,
- &Image->Info
- );
- if (EFI_ERROR (Status)) {
- goto Done;
- }
-
-
- //
- // Success. Return the image handle
- //
- *ImageHandle = Image->Handle;
-
-Done:
- //
- // All done accessing the source file
- // If we allocated the Source buffer, free it
- //
- if (FHand.FreeBuffer) {
- CoreFreePool (FHand.Source);
- }
-
- //
- // There was an error. If there's an Image structure, free it
- //
- if (EFI_ERROR (Status)) {
- if (Image != NULL) {
- CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0));
- *ImageHandle = NULL;
- }
- } else if (EFI_ERROR (SecurityStatus)) {
- Status = SecurityStatus;
- }
-
- return Status;
-}
-
-
-
-EFI_STATUS
-EFIAPI
-CoreLoadImage (
- IN BOOLEAN BootPolicy,
- IN EFI_HANDLE ParentImageHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- IN VOID *SourceBuffer OPTIONAL,
- IN UINTN SourceSize,
- OUT EFI_HANDLE *ImageHandle
- )
-/*++
-
-Routine Description:
-
- Loads an EFI image into memory and returns a handle to the image.
-
-Arguments:
-
- BootPolicy - 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.
- ParentImageHandle - The caller's image handle.
- FilePath - The specific file path from which the image is loaded.
- SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
- the image to be loaded.
- SourceSize - The size in bytes of SourceBuffer.
- ImageHandle - Pointer to the returned image handle that is created when the image
- is successfully loaded.
-
-Returns:
-
- EFI_SUCCESS - The image was loaded into memory.
- EFI_NOT_FOUND - The FilePath was not found.
- EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
- EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
- parsed to locate the proper protocol for loading the file.
- EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
---*/
-{
- EFI_STATUS Status;
-
- PERF_START (NULL, "LoadImage", NULL, 0);
-
- Status = CoreLoadImageCommon (
- BootPolicy,
- ParentImageHandle,
- FilePath,
- SourceBuffer,
- SourceSize,
- (EFI_PHYSICAL_ADDRESS) (UINTN) NULL,
- NULL,
- ImageHandle,
- NULL,
- EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION
- );
-
- PERF_END (NULL, "LoadImage", NULL, 0);
-
- return Status;
-}
-
-
-EFI_STATUS
-EFIAPI
-CoreLoadImageEx (
- IN EFI_PE32_IMAGE_PROTOCOL *This,
- IN EFI_HANDLE ParentImageHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- IN VOID *SourceBuffer OPTIONAL,
- IN UINTN SourceSize,
- IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
- OUT UINTN *NumberOfPages OPTIONAL,
- OUT EFI_HANDLE *ImageHandle,
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
- IN UINT32 Attribute
- )
-/*++
-
-Routine Description:
-
- Loads an EFI image into memory and returns a handle to the image with extended parameters.
-
-Arguments:
-
- This - Calling context
- ParentImageHandle - The caller's image handle.
- FilePath - The specific file path from which the image is loaded.
- SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
- the image to be loaded.
- SourceSize - The size in bytes of SourceBuffer.
- DstBuffer - The buffer to store the image.
- NumberOfPages - For input, specifies the space size of the image by caller if not NULL.
- For output, specifies the actual space size needed.
- ImageHandle - Image handle for output.
- EntryPoint - Image entry point for output.
- Attribute - The bit mask of attributes to set for the load PE image.
-
-Returns:
-
- EFI_SUCCESS - The image was loaded into memory.
- EFI_NOT_FOUND - The FilePath was not found.
- EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
- EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
- parsed to locate the proper protocol for loading the file.
- EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
---*/
-{
- return CoreLoadImageCommon (
- TRUE,
- ParentImageHandle,
- FilePath,
- SourceBuffer,
- SourceSize,
- DstBuffer,
- NumberOfPages,
- ImageHandle,
- EntryPoint,
- Attribute
- );
-}
-
-
-
-
-EFI_STATUS
-EFIAPI
-CoreStartImage (
- IN EFI_HANDLE ImageHandle,
- OUT UINTN *ExitDataSize,
- OUT CHAR16 **ExitData OPTIONAL
- )
-/*++
-
-Routine Description:
-
- Transfer control to a loaded image's entry point.
-
-Arguments:
-
- ImageHandle - Handle of image to be started.
-
- ExitDataSize - Pointer of the size to ExitData
-
- ExitData - Pointer to a pointer to a data buffer that includes a Null-terminated
- Unicode string, optionally followed by additional binary data. The string
- is a description that the caller may use to further indicate the reason for
- the image's exit.
-
-Returns:
-
- EFI_INVALID_PARAMETER - Invalid parameter
-
- EFI_OUT_OF_RESOURCES - No enough buffer to allocate
-
- EFI_SUCCESS - Successfully transfer control to the image's entry point.
-
---*/
-{
- EFI_STATUS Status;
- LOADED_IMAGE_PRIVATE_DATA *Image;
- LOADED_IMAGE_PRIVATE_DATA *LastImage;
- UINT64 HandleDatabaseKey;
- UINTN SetJumpFlag;
-
- Image = CoreLoadedImageInfo (ImageHandle);
- if (Image == NULL_HANDLE || Image->Started) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Don't profile Objects or invalid start requests
- //
- PERF_START (ImageHandle, START_IMAGE_TOK, NULL, 0);
-
-
- //
- // Push the current start image context, and
- // link the current image to the head. This is the
- // only image that can call Exit()
- //
- HandleDatabaseKey = CoreGetHandleDatabaseKey ();
- LastImage = mCurrentImage;
- mCurrentImage = Image;
- Image->Tpl = gEfiCurrentTpl;
-
- //
- // Set long jump for Exit() support
- // JumpContext must be aligned on a CPU specific boundary.
- // Overallocate the buffer and force the required alignment
- //
- Image->JumpBuffer = CoreAllocateBootServicesPool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);
- if (Image->JumpBuffer == NULL) {
- PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);
- return EFI_OUT_OF_RESOURCES;
- }
- Image->JumpContext = ALIGN_POINTER (Image->JumpBuffer, BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);
-
- SetJumpFlag = SetJump (Image->JumpContext);
- //
- // The initial call to SetJump() must always return 0.
- // Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().
- //
- if (!SetJumpFlag) {
- //
- // Call the image's entry point
- //
- Image->Started = TRUE;
- Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
-
- //
- // Add some debug information if the image returned with error.
- // This make the user aware and check if the driver image have already released
- // all the resource in this situation.
- //
- DEBUG_CODE_BEGIN ();
- if (EFI_ERROR (Image->Status)) {
- DEBUG ((EFI_D_ERROR, "Error: Image at %10p start failed: %r\n", Image->Info.ImageBase, Image->Status));
- }
- DEBUG_CODE_END ();
-
- //
- // If the image returns, exit it through Exit()
- //
- CoreExit (ImageHandle, Image->Status, 0, NULL);
- }
-
- //
- // Image has completed. Verify the tpl is the same
- //
- ASSERT (Image->Tpl == gEfiCurrentTpl);
- CoreRestoreTpl (Image->Tpl);
-
- CoreFreePool (Image->JumpBuffer);
-
- //
- // Pop the current start image context
- //
- mCurrentImage = LastImage;
-
- //
- // Go connect any handles that were created or modified while the image executed.
- //
- CoreConnectHandlesByKey (HandleDatabaseKey);
-
- //
- // Handle the image's returned ExitData
- //
- DEBUG_CODE_BEGIN ();
- if (Image->ExitDataSize != 0 || Image->ExitData != NULL) {
-
- DEBUG (
- (EFI_D_LOAD,
- "StartImage: ExitDataSize %d, ExitData %x",
- Image->ExitDataSize,
- Image->ExitData)
- );
- if (Image->ExitData != NULL) {
- DEBUG ((EFI_D_LOAD, " (%hs)", Image->ExitData));
- }
- DEBUG ((EFI_D_LOAD, "\n"));
- }
- DEBUG_CODE_END ();
-
- //
- // Return the exit data to the caller
- //
- if (ExitData != NULL && ExitDataSize != NULL) {
- *ExitDataSize = Image->ExitDataSize;
- *ExitData = Image->ExitData;
- } else {
- //
- // Caller doesn't want the exit data, free it
- //
- CoreFreePool (Image->ExitData);
- Image->ExitData = NULL;
- }
-
- //
- // Save the Status because Image will get destroyed if it is unloaded.
- //
- Status = Image->Status;
-
- //
- // If the image returned an error, or if the image is an application
- // unload it
- //
- if (EFI_ERROR (Image->Status) || Image->Type == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
- CoreUnloadAndCloseImage (Image, TRUE);
- }
-
- //
- // Done
- //
- PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);
- return Status;
-}
-
-
-VOID
-CoreUnloadAndCloseImage (
- IN LOADED_IMAGE_PRIVATE_DATA *Image,
- IN BOOLEAN FreePage
- )
-/*++
-
-Routine Description:
-
- Unloads EFI image from memory.
-
-Arguments:
-
- Image - EFI image
- FreePage - Free allocated pages
-
-Returns:
-
- None
-
---*/
-{
- EFI_STATUS Status;
- UINTN HandleCount;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleIndex;
- EFI_GUID **ProtocolGuidArray;
- UINTN ArrayCount;
- UINTN ProtocolIndex;
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
- UINTN OpenInfoCount;
- UINTN OpenInfoIndex;
-
- if (Image->Ebc != NULL) {
- //
- // If EBC protocol exists we must perform cleanups for this image.
- //
- Image->Ebc->UnloadImage (Image->Ebc, Image->Handle);
- }
-
- //
- // Unload image, free Image->ImageContext->ModHandle
- //
- gEfiPeiPeCoffLoader->UnloadImage (gEfiPeiPeCoffLoader, &Image->ImageContext);
-
- //
- // Free our references to the image handle
- //
- if (Image->Handle != NULL_HANDLE) {
-
- Status = CoreLocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (!EFI_ERROR (Status)) {
- for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
- Status = CoreProtocolsPerHandle (
- HandleBuffer[HandleIndex],
- &ProtocolGuidArray,
- &ArrayCount
- );
- if (!EFI_ERROR (Status)) {
- for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
- Status = CoreOpenProtocolInformation (
- HandleBuffer[HandleIndex],
- ProtocolGuidArray[ProtocolIndex],
- &OpenInfo,
- &OpenInfoCount
- );
- if (!EFI_ERROR (Status)) {
- for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
- if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {
- Status = CoreCloseProtocol (
- HandleBuffer[HandleIndex],
- ProtocolGuidArray[ProtocolIndex],
- Image->Handle,
- OpenInfo[OpenInfoIndex].ControllerHandle
- );
- }
- }
- if (OpenInfo != NULL) {
- CoreFreePool(OpenInfo);
- }
- }
- }
- if (ProtocolGuidArray != NULL) {
- CoreFreePool(ProtocolGuidArray);
- }
- }
- }
- if (HandleBuffer != NULL) {
- CoreFreePool (HandleBuffer);
- }
- }
-
- CoreRemoveDebugImageInfoEntry (Image->Handle);
-
- Status = CoreUninstallProtocolInterface (
- Image->Handle,
- &gEfiLoadedImageProtocolGuid,
- &Image->Info
- );
- }
-
- if (Image->RuntimeData != NULL) {
- if (Image->RuntimeData->Link.ForwardLink != NULL) {
- //
- // Remove the Image from the Runtime Image list as we are about to Free it!
- //
- RemoveEntryList (&Image->RuntimeData->Link);
- }
- CoreFreePool (Image->RuntimeData);
- }
-
- //
- // Free the Image from memory
- //
- if ((Image->ImageBasePage != 0) && FreePage) {
- CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);
- }
-
- //
- // Done with the Image structure
- //
- if (Image->Info.FilePath != NULL) {
- CoreFreePool (Image->Info.FilePath);
- }
-
- if (Image->FixupData != NULL) {
- CoreFreePool (Image->FixupData);
- }
-
- CoreFreePool (Image);
-}
-
-
-
-EFI_STATUS
-EFIAPI
-CoreExit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_STATUS Status,
- IN UINTN ExitDataSize,
- IN CHAR16 *ExitData OPTIONAL
- )
-/*++
-
-Routine Description:
-
- Terminates the currently loaded EFI image and returns control to boot services.
-
-Arguments:
-
- ImageHandle - Handle that identifies the image. This parameter is passed to the image
- on entry.
- Status - The image's exit code.
- ExitDataSize - The size, in bytes, of ExitData. Ignored if ExitStatus is
- EFI_SUCCESS.
- ExitData - Pointer to a data buffer that includes a Null-terminated Unicode string,
- optionally followed by additional binary data. The string is a
- description that the caller may use to further indicate the reason for
- the image's exit.
-
-Returns:
-
- EFI_INVALID_PARAMETER - Image handle is NULL or it is not current image.
-
- EFI_SUCCESS - Successfully terminates the currently loaded EFI image.
-
- EFI_ACCESS_DENIED - Should never reach there.
-
- EFI_OUT_OF_RESOURCES - Could not allocate pool
-
---*/
-{
- LOADED_IMAGE_PRIVATE_DATA *Image;
- EFI_TPL OldTpl;
-
- //
- // Prevent possible reentrance to this function
- // for the same ImageHandle
- //
- OldTpl = CoreRaiseTpl (TPL_NOTIFY);
-
- Image = CoreLoadedImageInfo (ImageHandle);
- if (Image == NULL_HANDLE) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if (!Image->Started) {
- //
- // The image has not been started so just free its resources
- //
- CoreUnloadAndCloseImage (Image, TRUE);
- Status = EFI_SUCCESS;
- goto Done;
- }
-
- //
- // Image has been started, verify this image can exit
- //
- if (Image != mCurrentImage) {
- DEBUG ((EFI_D_LOAD|EFI_D_ERROR, "Exit: Image is not exitable image\n"));
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- //
- // Set status
- //
- Image->Status = Status;
-
- //
- // If there's ExitData info, move it
- //
- if (ExitData != NULL) {
- Image->ExitDataSize = ExitDataSize;
- Image->ExitData = CoreAllocateBootServicesPool (Image->ExitDataSize);
- if (Image->ExitData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- CopyMem (Image->ExitData, ExitData, Image->ExitDataSize);
- }
-
- CoreRestoreTpl (OldTpl);
- //
- // return to StartImage
- //
- LongJump (Image->JumpContext, (UINTN)-1);
-
- //
- // If we return from LongJump, then it is an error
- //
- ASSERT (FALSE);
- Status = EFI_ACCESS_DENIED;
-Done:
- CoreRestoreTpl (OldTpl);
- return Status;
-}
-
-
-
-EFI_STATUS
-EFIAPI
-CoreUnloadImage (
- IN EFI_HANDLE ImageHandle
- )
-/*++
-
-Routine Description:
-
- Unloads an image.
-
-Arguments:
-
- ImageHandle - Handle that identifies the image to be unloaded.
-
-Returns:
-
- EFI_SUCCESS - The image has been unloaded.
- EFI_UNSUPPORTED - The image has been sarted, and does not support unload.
- EFI_INVALID_PARAMPETER - ImageHandle is not a valid image handle.
-
---*/
-{
- EFI_STATUS Status;
- LOADED_IMAGE_PRIVATE_DATA *Image;
- EFI_TPL OldTpl;
-
- //
- // Prevent possible reentrance to this function
- // for the same ImageHandle
- //
- OldTpl = CoreRaiseTpl (TPL_NOTIFY);
-
- Image = CoreLoadedImageInfo (ImageHandle);
- if (Image == NULL ) {
- //
- // The image handle is not valid
- //
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
-
- if (Image->Started) {
- //
- // The image has been started, request it to unload.
- //
- Status = EFI_UNSUPPORTED;
- if (Image->Info.Unload != NULL) {
- Status = Image->Info.Unload (ImageHandle);
- }
-
- } else {
- //
- // This Image hasn't been started, thus it can be unloaded
- //
- Status = EFI_SUCCESS;
- }
-
-
- if (!EFI_ERROR (Status)) {
- //
- // if the Image was not started or Unloaded O.K. then clean up
- //
- CoreUnloadAndCloseImage (Image, TRUE);
- }
-
-Done:
- CoreRestoreTpl (OldTpl);
- return Status;
-}
-
-
-EFI_STATUS
-EFIAPI
-CoreUnloadImageEx (
- IN EFI_PE32_IMAGE_PROTOCOL *This,
- IN EFI_HANDLE ImageHandle
- )
-/*++
-
-Routine Description:
-
- Unload the specified image.
-
-Arguments:
-
- This - Indicates the calling context.
-
- ImageHandle - The specified image handle.
-
-Returns:
-
- EFI_INVALID_PARAMETER - Image handle is NULL.
-
- EFI_UNSUPPORTED - Attempt to unload an unsupported image.
-
- EFI_SUCCESS - Image successfully unloaded.
-
---*/
-{
- return CoreUnloadImage (ImageHandle);
-}
diff --git a/EdkModulePkg/Core/Dxe/Image/ImageFile.c b/EdkModulePkg/Core/Dxe/Image/ImageFile.c
deleted file mode 100644
index 408688c69f..0000000000
--- a/EdkModulePkg/Core/Dxe/Image/ImageFile.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*++
-
-Copyright (c) 2006, Intel Corporation
-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.
-
-Module Name:
-
- ImageFile.c
-
-
-Abstract:
-
-
-
-
-Revision History
-
---*/
-
-#include <DxeMain.h>
-
-EFI_STATUS
-CoreOpenImageFile (
- IN BOOLEAN BootPolicy,
- IN VOID *SourceBuffer OPTIONAL,
- IN UINTN SourceSize,
- IN OUT EFI_DEVICE_PATH_PROTOCOL *FilePath,
- OUT EFI_HANDLE *DeviceHandle,
- IN IMAGE_FILE_HANDLE *ImageFileHandle,
- OUT UINT32 *AuthenticationStatus
- )
-/*++
-
-Routine Description:
-
- Opens a file for (simple) reading. The simple read abstraction
- will access the file either from a memory copy, from a file
- system interface, or from the load file interface.
-
-Arguments:
-
- BootPolicy - Policy for Open Image File.
- SourceBuffer - Pointer to the memory location containing copy
- of the image to be loaded.
- SourceSize - The size in bytes of SourceBuffer.
- FilePath - The specific file path from which the image is loaded
- DeviceHandle - Pointer to the return device handle.
- ImageFileHandle - Pointer to the image file handle.
- AuthenticationStatus - Pointer to a caller-allocated UINT32 in which the authentication status is returned.
-
-Returns:
-
- EFI_SUCCESS - Image file successfully opened.
-
- EFI_LOAD_ERROR - If the caller passed a copy of the file, and SourceSize is 0.
-
- EFI_INVALID_PARAMETER - File path is not valid.
-
- EFI_NOT_FOUND - File not found.
-
---*/
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *TempFilePath;
- FILEPATH_DEVICE_PATH *FilePathNode;
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FwVolFilePathNode;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
- EFI_FILE_HANDLE FileHandle;
- EFI_FILE_HANDLE LastHandle;
- EFI_LOAD_FILE_PROTOCOL *LoadFile;
- EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
- EFI_SECTION_TYPE SectionType;
- UINT8 *Pe32Buffer;
- UINTN Pe32BufferSize;
- EFI_FV_FILETYPE Type;
- EFI_FV_FILE_ATTRIBUTES Attrib;
- EFI_FILE_INFO *FileInfo;
- UINTN FileInfoSize;
- EFI_GUID *NameGuid;
-
- *AuthenticationStatus = 0;
- ZeroMem (ImageFileHandle, sizeof (IMAGE_FILE_HANDLE));
- ImageFileHandle->Signature = IMAGE_FILE_HANDLE_SIGNATURE;
-
- //
- // If the caller passed a copy of the file, then just use it
- //
- if (SourceBuffer != NULL) {
- ImageFileHandle->Source = SourceBuffer;
- ImageFileHandle->SourceSize = SourceSize;
- *DeviceHandle = NULL;
- if (SourceSize > 0) {
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_LOAD_ERROR;
- }
- goto Done;
- }
-
- //
- // Make sure FilePath is valid
- //
- if (FilePath == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check to see if it's in a Firmware Volume
- //
- FwVolFilePathNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)FilePath;
- Status = CoreDevicePathToInterface (
- &gEfiFirmwareVolumeProtocolGuid,
- (EFI_DEVICE_PATH_PROTOCOL **)&FwVolFilePathNode,
- (VOID*)&FwVol,
- DeviceHandle
- );
- if (!EFI_ERROR (Status)) {
- //
- // For FwVol File system there is only a single file name that is a GUID.
- //
- NameGuid = EfiGetNameGuidFromFwVolDevicePathNode (FwVolFilePathNode);
- if (NameGuid != NULL) {
-
- SectionType = EFI_SECTION_PE32;
- Pe32Buffer = NULL;
- Status = FwVol->ReadSection (
- FwVol,
- NameGuid,
- SectionType,
- 0,
- (VOID **)&Pe32Buffer,
- &Pe32BufferSize,
- AuthenticationStatus
- );
- if (EFI_ERROR (Status)) {
- //
- // Try a raw file, since a PE32 SECTION does not exist
- //
- if (Pe32Buffer != NULL) {
- CoreFreePool (Pe32Buffer);
- *AuthenticationStatus = 0;
- }
- Pe32Buffer = NULL;
- Status = FwVol->ReadFile (
- FwVol,
- NameGuid,
- (VOID **)&Pe32Buffer,
- &Pe32BufferSize,
- &Type,
- &Attrib,
- AuthenticationStatus
- );
- }
-
- if (!EFI_ERROR (Status)) {
- //
- // One of the reads passed so we are done
- //
- ImageFileHandle->Source = Pe32Buffer;
- ImageFileHandle->SourceSize = Pe32BufferSize;
- ImageFileHandle->FreeBuffer = TRUE;
- goto Done;
- }
- }
- }
-
- //
- // Attempt to access the file via a file system interface
- //
- FilePathNode = (FILEPATH_DEVICE_PATH *) FilePath;
- Status = CoreDevicePathToInterface (
- &gEfiSimpleFileSystemProtocolGuid,
- (EFI_DEVICE_PATH_PROTOCOL **)&FilePathNode,
- (VOID*)&Volume,
- DeviceHandle
- );
- 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 (&FilePathNode->Header)) {
- if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
- DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {
- Status = EFI_UNSUPPORTED;
- }
-
- if (EFI_ERROR (Status)) {
- //
- // Exit loop on Error
- //
- break;
- }
-
- LastHandle = FileHandle;
- FileHandle = NULL;
- Status = LastHandle->Open (
- LastHandle,
- &FileHandle,
- FilePathNode->PathName,
- EFI_FILE_MODE_READ,
- 0
- );
-
- //
- // Close the previous node
- //
- LastHandle->Close (LastHandle);
-
- FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
- }
-
- 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 = sizeof (EFI_FILE_INFO);
- while (CoreGrowBuffer (&Status, (VOID **)&FileInfo, FileInfoSize)) {
- //
- // Automatically allocate buffer of the correct size and make the call
- //
- Status = FileHandle->GetInfo (
- FileHandle,
- &gEfiFileInfoGuid,
- &FileInfoSize,
- FileInfo
- );
- }
- if (!EFI_ERROR (Status)) {
- //
- // Allocate space for the file
- //
- ImageFileHandle->Source = CoreAllocateBootServicesPool ((UINTN)FileInfo->FileSize);
- if (ImageFileHandle->Source != NULL) {
- //
- // Read the file into the buffer we allocated
- //
- ImageFileHandle->SourceSize = (UINTN)FileInfo->FileSize;
- ImageFileHandle->FreeBuffer = TRUE;
- Status = FileHandle->Read (FileHandle, &ImageFileHandle->SourceSize, ImageFileHandle->Source);
-
- //
- // Close the file since we are done
- //
- FileHandle->Close (FileHandle);
- } else {
- Status = EFI_OUT_OF_RESOURCES;
- }
-
- goto Done;
- }
- }
- }
- }
-
-
- //
- // Try LoadFile style
- //
-
- TempFilePath = FilePath;
- Status = CoreDevicePathToInterface (
- &gEfiLoadFileProtocolGuid,
- &TempFilePath,
- (VOID*)&LoadFile,
- DeviceHandle
- );
- if (!EFI_ERROR (Status)) {
- //
- // Call LoadFile with the correct buffer size
- //
- while (CoreGrowBuffer (&Status, (VOID **)&ImageFileHandle->Source, ImageFileHandle->SourceSize)) {
- Status = LoadFile->LoadFile (
- LoadFile,
- TempFilePath,
- BootPolicy,
- &ImageFileHandle->SourceSize,
- ImageFileHandle->Source
- );
- //
- // If success or other error happens, stop loop
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- break;
- }
- }
-
- if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
- ImageFileHandle->FreeBuffer = TRUE;
- goto Done;
- }
- }
-
- //
- // Nothing else to try
- //
- DEBUG ((EFI_D_LOAD|EFI_D_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));
- Status = EFI_NOT_FOUND;
-
-Done:
-
- //
- // If the file was not accessed, clean up
- //
- if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
- if (ImageFileHandle->FreeBuffer) {
- //
- // Free the source buffer if we allocated it
- //
- CoreFreePool (ImageFileHandle->Source);
- }
- }
-
- return Status;
-}
-
-
-
-EFI_STATUS
-EFIAPI
-CoreReadImageFile (
- IN VOID *UserHandle,
- IN UINTN Offset,
- IN OUT UINTN *ReadSize,
- OUT VOID *Buffer
- )
-/*++
-
-Routine Description:
-
- Read image file (specified by UserHandle) into user specified buffer with specified offset
- and length.
-
-Arguments:
-
- UserHandle - Image file handle
-
- Offset - Offset to the source file
-
- ReadSize - For input, pointer of size to read;
- For output, pointer of size actually read.
-
- Buffer - Buffer to write into
-
-Returns:
-
- EFI_SUCCESS - Successfully read the specified part of file into buffer.
-
---*/
-{
- UINTN EndPosition;
- IMAGE_FILE_HANDLE *FHand;
-
- FHand = (IMAGE_FILE_HANDLE *)UserHandle;
- ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);
-
- //
- // Move data from our local copy of the file
- //
- EndPosition = Offset + *ReadSize;
- if (EndPosition > FHand->SourceSize) {
- *ReadSize = (UINT32)(FHand->SourceSize - Offset);
- }
- if (Offset >= FHand->SourceSize) {
- *ReadSize = 0;
- }
-
- CopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-CoreDevicePathToInterface (
- IN EFI_GUID *Protocol,
- IN EFI_DEVICE_PATH_PROTOCOL **FilePath,
- OUT VOID **Interface,
- OUT EFI_HANDLE *Handle
- )
-/*++
-
-Routine Description:
-
- Search a handle to a device on a specified device path that supports a specified protocol,
- interface of that protocol on that handle is another output.
-
-Arguments:
-
- Protocol - The protocol to search for
-
- FilePath - The specified device path
-
- Interface - Interface of the protocol on the handle
-
- Handle - The handle to the device on the specified device path that supports the protocol.
-
-Returns:
-
- Status code.
-
---*/
-{
- EFI_STATUS Status;
-
- Status = CoreLocateDevicePath (Protocol, FilePath, Handle);
- if (!EFI_ERROR (Status)) {
- Status = CoreHandleProtocol (*Handle, Protocol, Interface);
- }
- return Status;
-}
-
-BOOLEAN
-CoreGrowBuffer (
- IN OUT EFI_STATUS *Status,
- IN OUT VOID **Buffer,
- IN UINTN BufferSize
- )
-/*++
-
-Routine Description:
-
- Helper function called as part of the code needed
- to allocate the proper sized buffer for various
- EFI interfaces.
-
-Arguments:
-
- Status - Current status
-
- Buffer - Current allocated buffer, or NULL
-
- BufferSize - Current buffer size needed
-
-Returns:
-
- TRUE - if the buffer was reallocated and the caller
- should try the API again.
-
- FALSE - buffer could not be allocated and the caller
- should not try the API again.
-
---*/
-{
- BOOLEAN TryAgain;
-
- TryAgain = FALSE;
- //
- // If this is an initial request, buffer will be null with a new buffer size
- //
- if (*Buffer == NULL) {
- *Status = EFI_BUFFER_TOO_SMALL;
- }
-
- if (BufferSize == 0) {
- return TRUE;
- }
-
- //
- // If the status code is "buffer too small", resize the buffer
- //
-
- if (*Status == EFI_BUFFER_TOO_SMALL) {
- if (*Buffer != NULL) {
- CoreFreePool (*Buffer);
- }
-
- *Buffer = CoreAllocateBootServicesPool (BufferSize);
- if (*Buffer != NULL) {
- TryAgain = TRUE;
- } else {
- *Status = EFI_OUT_OF_RESOURCES;
- }
- }
-
- //
- // If there's an error, free the buffer
- //
- if ((!TryAgain) && (EFI_ERROR (*Status)) && (*Buffer)) {
- CoreFreePool (*Buffer);
- *Buffer = NULL;
- }
-
- return TryAgain;
-}
-