--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ GetImage.c\r
+\r
+Abstract:\r
+\r
+ Image data extraction support for common use.\r
+\r
+--*/\r
+\r
+#include "Tiano.h"\r
+#include "EfiDriverLib.h"\r
+#include "EfiImageFormat.h"\r
+\r
+#include EFI_PROTOCOL_CONSUMER (LoadedImage)\r
+\r
+EFI_STATUS\r
+GetImageFromFv (\r
+#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,\r
+#else\r
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,\r
+#endif\r
+ IN EFI_GUID *NameGuid,\r
+ IN EFI_SECTION_TYPE SectionType,\r
+ OUT VOID **Buffer,\r
+ OUT UINTN *Size\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FV_FILETYPE FileType;\r
+ EFI_FV_FILE_ATTRIBUTES Attributes;\r
+ UINT32 AuthenticationStatus;\r
+\r
+ //\r
+ // Read desired section content in NameGuid file\r
+ //\r
+ *Buffer = NULL;\r
+ *Size = 0;\r
+ Status = Fv->ReadSection (\r
+ Fv,\r
+ NameGuid,\r
+ SectionType,\r
+ 0,\r
+ Buffer,\r
+ Size,\r
+ &AuthenticationStatus\r
+ );\r
+\r
+ if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
+ //\r
+ // Try reading PE32 section, since the TE section does not exist\r
+ //\r
+ *Buffer = NULL;\r
+ *Size = 0;\r
+ Status = Fv->ReadSection (\r
+ Fv,\r
+ NameGuid,\r
+ EFI_SECTION_PE32,\r
+ 0,\r
+ Buffer,\r
+ Size,\r
+ &AuthenticationStatus\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status) && \r
+ ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) {\r
+ //\r
+ // Try reading raw file, since the desired section does not exist\r
+ //\r
+ *Buffer = NULL;\r
+ *Size = 0;\r
+ Status = Fv->ReadFile (\r
+ Fv,\r
+ NameGuid,\r
+ Buffer,\r
+ Size,\r
+ &FileType,\r
+ &Attributes,\r
+ &AuthenticationStatus\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+GetImage (\r
+ IN EFI_GUID *NameGuid,\r
+ IN EFI_SECTION_TYPE SectionType,\r
+ OUT VOID **Buffer,\r
+ OUT UINTN *Size\r
+ )\r
+{\r
+ return GetImageEx (NULL, NameGuid, SectionType, Buffer, Size, FALSE);\r
+}\r
+\r
+EFI_STATUS\r
+GetImageEx (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_GUID *NameGuid,\r
+ IN EFI_SECTION_TYPE SectionType,\r
+ OUT VOID **Buffer,\r
+ OUT UINTN *Size,\r
+ BOOLEAN WithinImageFv\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN HandleCount;\r
+ UINTN Index;\r
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+#if (PI_SPECIFICATION_VERSION < 0x00010000)\r
+ EFI_FIRMWARE_VOLUME_PROTOCOL *ImageFv;\r
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;\r
+#else\r
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;\r
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
+#endif\r
+\r
+ if (ImageHandle == NULL && WithinImageFv) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EFI_NOT_FOUND;\r
+ ImageFv = NULL;\r
+ if (ImageHandle != NULL) {\r
+ Status = gBS->HandleProtocol (\r
+ ImageHandle,\r
+ &gEfiLoadedImageProtocolGuid,\r
+ &LoadedImage\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Status = gBS->HandleProtocol (\r
+ LoadedImage->DeviceHandle,\r
+ #if (PI_SPECIFICATION_VERSION < 0x00010000) \r
+ &gEfiFirmwareVolumeProtocolGuid,\r
+ #else\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ #endif\r
+ &ImageFv\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);\r
+ }\r
+ }\r
+\r
+ if (Status == EFI_SUCCESS || WithinImageFv) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)\r
+ &gEfiFirmwareVolumeProtocolGuid,\r
+ #else\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ #endif\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Find desired image in all Fvs\r
+ //\r
+ for (Index = 0; Index < HandleCount; ++Index) {\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)\r
+ &gEfiFirmwareVolumeProtocolGuid,\r
+ #else\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ #endif\r
+ (VOID**)&Fv\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool(HandleBuffer);\r
+ return Status;\r
+ }\r
+\r
+ if (ImageFv != NULL && Fv == ImageFv) {\r
+ continue;\r
+ }\r
+\r
+ Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ }\r
+ gBS->FreePool(HandleBuffer);\r
+\r
+ //\r
+ // Not found image\r
+ //\r
+ if (Index == HandleCount) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r