+ if ((Image->ImageBasePage != 0) && FreePage) {\r
+ CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);\r
+ }\r
+\r
+ //\r
+ // Done with the Image structure\r
+ //\r
+ if (Image->Info.FilePath != NULL) {\r
+ CoreFreePool (Image->Info.FilePath);\r
+ }\r
+\r
+ if (Image->LoadedImageDevicePath != NULL) {\r
+ CoreFreePool (Image->LoadedImageDevicePath);\r
+ }\r
+\r
+ if (Image->FixupData != NULL) {\r
+ CoreFreePool (Image->FixupData);\r
+ }\r
+\r
+ CoreFreePool (Image);\r
+}\r
+\r
+\r
+/**\r
+ Loads an EFI image into memory and returns a handle to the image.\r
+\r
+ @param BootPolicy If TRUE, indicates that the request originates\r
+ from the boot manager, and that the boot\r
+ manager is attempting to load FilePath as a\r
+ boot selection.\r
+ @param ParentImageHandle The caller's image handle.\r
+ @param FilePath The specific file path from which the image is\r
+ loaded.\r
+ @param SourceBuffer If not NULL, a pointer to the memory location\r
+ containing a copy of the image to be loaded.\r
+ @param SourceSize The size in bytes of SourceBuffer.\r
+ @param DstBuffer The buffer to store the image\r
+ @param NumberOfPages If not NULL, it inputs a pointer to the page\r
+ number of DstBuffer and outputs a pointer to\r
+ the page number of the image. If this number is\r
+ not enough, return EFI_BUFFER_TOO_SMALL and\r
+ this parameter contains the required number.\r
+ @param ImageHandle Pointer to the returned image handle that is\r
+ created when the image is successfully loaded.\r
+ @param EntryPoint A pointer to the entry point\r
+ @param Attribute The bit mask of attributes to set for the load\r
+ PE image\r
+\r
+ @retval EFI_SUCCESS The image was loaded into memory.\r
+ @retval EFI_NOT_FOUND The FilePath was not found.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small\r
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device\r
+ path cannot be parsed to locate the proper\r
+ protocol for loading the file.\r
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient\r
+ resources.\r
+ @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not\r
+ understood.\r
+ @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error.\r
+ @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the \r
+ image from being loaded. NULL is returned in *ImageHandle.\r
+ @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a \r
+ valid EFI_LOADED_IMAGE_PROTOCOL. However, the current \r
+ platform policy specifies that the image should not be started.\r
+\r
+**/\r
+EFI_STATUS\r
+CoreLoadImageCommon (\r
+ IN BOOLEAN BootPolicy,\r
+ IN EFI_HANDLE ParentImageHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
+ IN VOID *SourceBuffer OPTIONAL,\r
+ IN UINTN SourceSize,\r
+ IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,\r
+ IN OUT UINTN *NumberOfPages OPTIONAL,\r
+ OUT EFI_HANDLE *ImageHandle,\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,\r
+ IN UINT32 Attribute\r
+ )\r
+{\r
+ LOADED_IMAGE_PRIVATE_DATA *Image;\r
+ LOADED_IMAGE_PRIVATE_DATA *ParentImage;\r
+ IMAGE_FILE_HANDLE FHand;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS SecurityStatus;\r
+ EFI_HANDLE DeviceHandle;\r
+ UINT32 AuthenticationStatus;\r
+ EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *InputFilePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *Node;\r
+ UINTN FilePathSize;\r
+ BOOLEAN ImageIsFromFv;\r
+ BOOLEAN ImageIsFromLoadFile;\r
+\r
+ SecurityStatus = EFI_SUCCESS;\r
+\r
+ ASSERT (gEfiCurrentTpl < TPL_NOTIFY);\r
+ ParentImage = NULL;\r
+\r
+ //\r
+ // The caller must pass in a valid ParentImageHandle\r
+ //\r
+ if (ImageHandle == NULL || ParentImageHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ ParentImage = CoreLoadedImageInfo (ParentImageHandle);\r
+ if (ParentImage == NULL) {\r
+ DEBUG((DEBUG_LOAD|DEBUG_ERROR, "LoadImageEx: Parent handle not an image handle\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ ZeroMem (&FHand, sizeof (IMAGE_FILE_HANDLE));\r
+ FHand.Signature = IMAGE_FILE_HANDLE_SIGNATURE;\r
+ OriginalFilePath = FilePath;\r
+ InputFilePath = FilePath;\r
+ HandleFilePath = FilePath;\r
+ DeviceHandle = NULL;\r
+ Status = EFI_SUCCESS;\r
+ AuthenticationStatus = 0;\r
+ ImageIsFromFv = FALSE;\r
+ ImageIsFromLoadFile = FALSE;\r
+\r
+ //\r
+ // If the caller passed a copy of the file, then just use it\r
+ //\r
+ if (SourceBuffer != NULL) {\r
+ FHand.Source = SourceBuffer;\r
+ FHand.SourceSize = SourceSize;\r
+ Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ DeviceHandle = NULL;\r
+ }\r
+ if (SourceSize > 0) {\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ Status = EFI_LOAD_ERROR;\r
+ }\r
+ } else {\r
+ if (FilePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Try to get the image device handle by checking the match protocol.\r
+ //\r
+ Node = NULL;\r
+ Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ ImageIsFromFv = TRUE;\r
+ } else {\r
+ HandleFilePath = FilePath;\r
+ Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ if (!BootPolicy) {\r
+ HandleFilePath = FilePath;\r
+ Status = CoreLocateDevicePath (&gEfiLoadFile2ProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ HandleFilePath = FilePath;\r
+ Status = CoreLocateDevicePath (&gEfiLoadFileProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ ImageIsFromLoadFile = TRUE;\r
+ Node = HandleFilePath;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Get the source file buffer by its device path.\r
+ //\r
+ FHand.Source = GetFileBufferByFilePath (\r
+ BootPolicy, \r
+ FilePath,\r
+ &FHand.SourceSize,\r
+ &AuthenticationStatus\r
+ );\r
+ if (FHand.Source == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ } else {\r
+ FHand.FreeBuffer = TRUE;\r
+ if (ImageIsFromLoadFile) {\r
+ //\r
+ // LoadFile () may cause the device path of the Handle be updated.\r
+ //\r
+ OriginalFilePath = AppendDevicePath (DevicePathFromHandle (DeviceHandle), Node);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ Image = NULL;\r
+ goto Done;\r