]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/GetImage.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiDriverLib / GetImage.c
1 /*++
2
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 GetImage.c
15
16 Abstract:
17
18 Image data extraction support for common use.
19
20 --*/
21
22 #include "Tiano.h"
23 #include "EfiDriverLib.h"
24 #include "EfiImageFormat.h"
25
26 #include EFI_PROTOCOL_CONSUMER (LoadedImage)
27
28 EFI_STATUS
29 GetImageFromFv (
30 #if (PI_SPECIFICATION_VERSION < 0x00010000)
31 IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
32 #else
33 IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
34 #endif
35 IN EFI_GUID *NameGuid,
36 IN EFI_SECTION_TYPE SectionType,
37 OUT VOID **Buffer,
38 OUT UINTN *Size
39 )
40 {
41 EFI_STATUS Status;
42 EFI_FV_FILETYPE FileType;
43 EFI_FV_FILE_ATTRIBUTES Attributes;
44 UINT32 AuthenticationStatus;
45
46 //
47 // Read desired section content in NameGuid file
48 //
49 *Buffer = NULL;
50 *Size = 0;
51 Status = Fv->ReadSection (
52 Fv,
53 NameGuid,
54 SectionType,
55 0,
56 Buffer,
57 Size,
58 &AuthenticationStatus
59 );
60
61 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
62 //
63 // Try reading PE32 section, since the TE section does not exist
64 //
65 *Buffer = NULL;
66 *Size = 0;
67 Status = Fv->ReadSection (
68 Fv,
69 NameGuid,
70 EFI_SECTION_PE32,
71 0,
72 Buffer,
73 Size,
74 &AuthenticationStatus
75 );
76 }
77
78 if (EFI_ERROR (Status) &&
79 ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) {
80 //
81 // Try reading raw file, since the desired section does not exist
82 //
83 *Buffer = NULL;
84 *Size = 0;
85 Status = Fv->ReadFile (
86 Fv,
87 NameGuid,
88 Buffer,
89 Size,
90 &FileType,
91 &Attributes,
92 &AuthenticationStatus
93 );
94 }
95
96 return Status;
97 }
98
99 EFI_STATUS
100 GetImage (
101 IN EFI_GUID *NameGuid,
102 IN EFI_SECTION_TYPE SectionType,
103 OUT VOID **Buffer,
104 OUT UINTN *Size
105 )
106 {
107 return GetImageEx (NULL, NameGuid, SectionType, Buffer, Size, FALSE);
108 }
109
110 EFI_STATUS
111 GetImageEx (
112 IN EFI_HANDLE ImageHandle,
113 IN EFI_GUID *NameGuid,
114 IN EFI_SECTION_TYPE SectionType,
115 OUT VOID **Buffer,
116 OUT UINTN *Size,
117 BOOLEAN WithinImageFv
118 )
119 {
120 EFI_STATUS Status;
121 EFI_HANDLE *HandleBuffer;
122 UINTN HandleCount;
123 UINTN Index;
124 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
125 #if (PI_SPECIFICATION_VERSION < 0x00010000)
126 EFI_FIRMWARE_VOLUME_PROTOCOL *ImageFv;
127 EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
128 #else
129 EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv;
130 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
131 #endif
132
133 if (ImageHandle == NULL && WithinImageFv) {
134 return EFI_INVALID_PARAMETER;
135 }
136
137 Status = EFI_NOT_FOUND;
138 ImageFv = NULL;
139 if (ImageHandle != NULL) {
140 Status = gBS->HandleProtocol (
141 ImageHandle,
142 &gEfiLoadedImageProtocolGuid,
143 &LoadedImage
144 );
145 if (EFI_ERROR (Status)) {
146 return Status;
147 }
148 Status = gBS->HandleProtocol (
149 LoadedImage->DeviceHandle,
150 #if (PI_SPECIFICATION_VERSION < 0x00010000)
151 &gEfiFirmwareVolumeProtocolGuid,
152 #else
153 &gEfiFirmwareVolume2ProtocolGuid,
154 #endif
155 &ImageFv
156 );
157 if (!EFI_ERROR (Status)) {
158 Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);
159 }
160 }
161
162 if (Status == EFI_SUCCESS || WithinImageFv) {
163 return Status;
164 }
165
166 Status = gBS->LocateHandleBuffer (
167 ByProtocol,
168 #if (PI_SPECIFICATION_VERSION < 0x00010000)
169 &gEfiFirmwareVolumeProtocolGuid,
170 #else
171 &gEfiFirmwareVolume2ProtocolGuid,
172 #endif
173 NULL,
174 &HandleCount,
175 &HandleBuffer
176 );
177 if (EFI_ERROR (Status)) {
178 return Status;
179 }
180
181 //
182 // Find desired image in all Fvs
183 //
184 for (Index = 0; Index < HandleCount; ++Index) {
185 Status = gBS->HandleProtocol (
186 HandleBuffer[Index],
187 #if (PI_SPECIFICATION_VERSION < 0x00010000)
188 &gEfiFirmwareVolumeProtocolGuid,
189 #else
190 &gEfiFirmwareVolume2ProtocolGuid,
191 #endif
192 (VOID**)&Fv
193 );
194
195 if (EFI_ERROR (Status)) {
196 gBS->FreePool(HandleBuffer);
197 return Status;
198 }
199
200 if (ImageFv != NULL && Fv == ImageFv) {
201 continue;
202 }
203
204 Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
205
206 if (!EFI_ERROR (Status)) {
207 break;
208 }
209 }
210 gBS->FreePool(HandleBuffer);
211
212 //
213 // Not found image
214 //
215 if (Index == HandleCount) {
216 return EFI_NOT_FOUND;
217 }
218
219 return EFI_SUCCESS;
220 }