]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/GetImage.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiDriverLib / GetImage.c
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/GetImage.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/GetImage.c
new file mode 100644 (file)
index 0000000..3d44562
--- /dev/null
@@ -0,0 +1,220 @@
+/*++\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