2 Mde PI library functions.
4 Copyright (c) 2007, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/DebugLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/PiLib.h>
20 #include <Protocol/FirmwareVolume2.h>
21 #include <Protocol/LoadedImage.h>
25 Internal function which read the image specified by Firmware File GUID name and
26 the Firmware Section tyep from a specified Firmware Volume
29 @param Fv The Firmware Volume Protocol instance.
30 @param NameGuid The GUID name of a Firmware File.
31 @param SectionType The Firmware Section type.
32 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
33 @param Size On output, the size of Buffer.
35 @retval EFI_SUCCESS The image is found and data and size is returned.
36 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
37 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
38 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
39 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
44 InternalGetImageFromFv (
45 IN EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
,
46 IN CONST EFI_GUID
*NameGuid
,
47 IN EFI_SECTION_TYPE SectionType
,
53 EFI_FV_FILETYPE FileType
;
54 EFI_FV_FILE_ATTRIBUTES Attributes
;
55 UINT32 AuthenticationStatus
;
58 // Read desired section content in NameGuid file
62 Status
= Fv
->ReadSection (
72 if (EFI_ERROR (Status
) && (SectionType
== EFI_SECTION_TE
)) {
74 // Try reading PE32 section, since the TE section does not exist
78 Status
= Fv
->ReadSection (
89 if (EFI_ERROR (Status
) &&
90 ((SectionType
== EFI_SECTION_TE
) || (SectionType
== EFI_SECTION_PE32
))) {
92 // Try reading raw file, since the desired section does not exist
96 Status
= Fv
->ReadFile (
103 &AuthenticationStatus
111 Allocate and fill a buffer with an image identified by a Firmware File GUID name and a Firmware Section type.
112 The Firmware Volumes to search for the Firmware File can be specified to be either all Firmware Volumes
113 in the system, or the Firmware Volume which contains the Firmware File specified by an image handle.
115 If ImageHandle is NULL, all Firmware Volumes in the system will be searched. If ImageHandle is not NULL,
116 ImageHandle is interpreted as EFI_PEI_FILE_HANDLE for the implementation of this function for PEI phase.
117 The input parameter ImageHandle is interpreted as EFI_HANDLE, on which an EFI_LOADED_IMAGE_PROTOCOL
118 is installed, for the implementation of this function for DXE phase. The search always starts from the FV
119 identified by ImageHandle. If WithinImageFv is TRUE, search will only be performed on the first FV. If WithinImageFv
120 is FALSE, search will continue on other FVs if it fails on the first FV. The search order of Firmware Volumes is
121 deterministic but arbitrary if no new firmware volume is added into the system between each search.
123 The search order for the section type specified by SectionType in the Firmware File is using a depth-first
124 and left-to-right algorithm through all sections. The first section found to match SectionType will be returned.
126 If SectionType is EFI_SECTION_PE32, EFI_SECTION_PE32 will be used as Firmware Section type
127 to read Firmware Section data from the Firmware File. If no such section exists, the function will try
128 to read a Firmware File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.
130 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section
131 data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to
132 read Firmware Section data from the Firmware File. If no such section exists, the function will try to read a Firmware
133 File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.
135 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
136 by this function. This function can only be called at TPL_NOTIFY and below.
138 If ImageHandle is NULL and WithinImage is TRUE, then ASSERT ();
139 If NameGuid is NULL, then ASSERT();
140 If Buffer is NULL, then ASSERT();
141 If Size is NULL, then ASSERT().
143 @param NameGuid The GUID name of a Firmware File.
144 @param SectionType The Firmware Section type.
145 @param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
146 @param Size On output, the size of Buffer.
148 @retval EFI_SUCCESS The image is found and data and size is returned.
149 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
150 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
151 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
152 @retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
158 GetSectionFromFvFile (
159 IN CONST VOID
*ImageHandle
,
160 IN CONST EFI_GUID
*NameGuid
,
161 IN EFI_SECTION_TYPE SectionType
,
164 IN BOOLEAN WithinImageFv
168 EFI_HANDLE
*HandleBuffer
;
171 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
172 EFI_FIRMWARE_VOLUME2_PROTOCOL
*ImageFv
;
173 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
175 ASSERT (NameGuid
!= NULL
);
176 ASSERT (Buffer
!= NULL
);
177 ASSERT (Size
!= NULL
);
178 ASSERT (!(ImageHandle
== NULL
&& WithinImageFv
));
180 Status
= EFI_NOT_FOUND
;
182 if (ImageHandle
!= NULL
) {
183 Status
= gBS
->HandleProtocol (
184 (EFI_HANDLE
*) ImageHandle
,
185 &gEfiLoadedImageProtocolGuid
,
186 (VOID
**) &LoadedImage
188 if (EFI_ERROR (Status
)) {
191 Status
= gBS
->HandleProtocol (
192 LoadedImage
->DeviceHandle
,
193 &gEfiFirmwareVolume2ProtocolGuid
,
196 if (!EFI_ERROR (Status
)) {
197 Status
= InternalGetImageFromFv (ImageFv
, NameGuid
, SectionType
, Buffer
, Size
);
201 if (Status
== EFI_SUCCESS
|| WithinImageFv
) {
206 Status
= gBS
->LocateHandleBuffer (
208 &gEfiFirmwareVolume2ProtocolGuid
,
213 if (EFI_ERROR (Status
)) {
218 // Find desired image in all Fvs
220 for (Index
= 0; Index
< HandleCount
; ++Index
) {
221 Status
= gBS
->HandleProtocol (
223 &gEfiFirmwareVolume2ProtocolGuid
,
227 if (EFI_ERROR (Status
)) {
231 if (ImageFv
!= NULL
&& Fv
== ImageFv
) {
235 Status
= InternalGetImageFromFv (Fv
, NameGuid
, SectionType
, Buffer
, Size
);
237 if (!EFI_ERROR (Status
)) {
245 if (Index
== HandleCount
) {
246 Status
= EFI_NOT_FOUND
;
251 if (HandleBuffer
!= NULL
) {
252 FreePool(HandleBuffer
);
260 ImageHandleToFvHandle (
261 EFI_HANDLE ImageHandle
265 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
267 ASSERT (ImageHandle
!= NULL
);
269 Status
= gBS
->HandleProtocol (
270 (EFI_HANDLE
*) ImageHandle
,
271 &gEfiLoadedImageProtocolGuid
,
272 (VOID
**) &LoadedImage
275 ASSERT_EFI_ERROR (Status
);
277 return LoadedImage
->DeviceHandle
;
283 GetSectionFromAnyFv (
284 IN CONST EFI_GUID
*NameGuid
,
285 IN EFI_SECTION_TYPE SectionType
,
292 EFI_HANDLE
*HandleBuffer
;
299 // Search the FV that contain the caller's FFS first.
300 // FV builder can choose to build FFS into the this FV
301 // so that this implementation of GetSectionFromAnyFv
302 // will locate the FFS faster.
304 FvHandle
= ImageHandleToFvHandle (gImageHandle
);
305 Status
= GetSectionFromFv (
313 if (!EFI_ERROR (Status
)) {
317 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
320 Status
= gBS
->LocateHandleBuffer (
322 &gEfiFirmwareVolume2ProtocolGuid
,
327 if (EFI_ERROR (Status
)) {
331 for (Index
= 0; Index
< HandleCount
; ++Index
) {
333 // Skip the FV that contain the caller's FFS
335 if (HandleBuffer
[Index
] == FvHandle
) {
339 Status
= GetSectionFromFv (
348 if (!EFI_ERROR (Status
)) {
353 if (Index
== HandleCount
) {
354 Status
= EFI_NOT_FOUND
;
359 gBS
->RestoreTPL (OldTpl
);
361 if (HandleBuffer
!= NULL
) {
362 FreePool(HandleBuffer
);
371 IN EFI_HANDLE FvHandle
,
372 IN CONST EFI_GUID
*NameGuid
,
373 IN EFI_SECTION_TYPE SectionType
,
380 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
381 UINT32 AuthenticationStatus
;
383 ASSERT (FvHandle
!= NULL
);
385 Status
= gBS
->HandleProtocol (
387 &gEfiFirmwareVolume2ProtocolGuid
,
390 if (EFI_ERROR (Status
)) {
395 // Read desired section content in NameGuid file
399 Status
= Fv
->ReadSection (
406 &AuthenticationStatus
409 if (EFI_ERROR (Status
) && (SectionType
== EFI_SECTION_TE
)) {
411 // Try reading PE32 section, if the required section is TE type
415 Status
= Fv
->ReadSection (
422 &AuthenticationStatus
432 GetSectionFromCurrentFv (
433 IN CONST EFI_GUID
*NameGuid
,
434 IN EFI_SECTION_TYPE SectionType
,
440 return GetSectionFromFv(
441 ImageHandleToFvHandle(gImageHandle
),
454 GetSectionFromCurrentFfs (
455 IN EFI_SECTION_TYPE SectionType
,
461 return GetSectionFromFv(
462 ImageHandleToFvHandle(gImageHandle
),