]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxeServicesLib/DxeServicesLib.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / DxeServicesLib / DxeServicesLib.c
CommitLineData
1c280088 1/** @file\r
9095d37b 2 MDE DXE Services Library provides functions that simplify the development of DXE Drivers.\r
84716614 3 These functions help access data from sections of FFS files or from file path.\r
1c280088 4\r
9095d37b 5 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
711ef3f6 6 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
9344f092 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1c280088 8\r
9**/\r
10\r
11#include <PiDxe.h>\r
12#include <Library/DebugLib.h>\r
13#include <Library/MemoryAllocationLib.h>\r
14#include <Library/UefiBootServicesTableLib.h>\r
84716614
LG
15#include <Library/DevicePathLib.h>\r
16#include <Library/UefiLib.h>\r
eb9dd4d0 17#include <Library/DxeServicesLib.h>\r
1c280088 18#include <Protocol/FirmwareVolume2.h>\r
19#include <Protocol/LoadedImage.h>\r
84716614
LG
20#include <Protocol/LoadFile2.h>\r
21#include <Protocol/LoadFile.h>\r
22#include <Protocol/SimpleFileSystem.h>\r
23#include <Guid/FileInfo.h>\r
1c280088 24\r
25/**\r
166152e8 26 Identify the device handle from which the Image is loaded from. As this device handle is passed to\r
9095d37b 27 GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL\r
c1d8b697 28 protocol instance should be located successfully by calling gBS->HandleProtocol ().\r
1c280088 29\r
166152e8 30 This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed\r
31 on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.\r
9095d37b 32\r
166152e8 33 If ImageHandle is NULL, then ASSERT ();\r
34 If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();\r
9095d37b 35\r
166152e8 36 @param ImageHandle The firmware allocated handle for UEFI image.\r
1c280088 37\r
58380e9c 38 @retval EFI_HANDLE The device handle from which the Image is loaded from.\r
1c280088 39\r
40**/\r
166152e8 41EFI_HANDLE\r
42InternalImageHandleToFvHandle (\r
2f88bd3a 43 EFI_HANDLE ImageHandle\r
166152e8 44 )\r
45{\r
2f88bd3a
MK
46 EFI_STATUS Status;\r
47 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
9095d37b 48\r
166152e8 49 ASSERT (ImageHandle != NULL);\r
50\r
51 Status = gBS->HandleProtocol (\r
2f88bd3a
MK
52 ImageHandle,\r
53 &gEfiLoadedImageProtocolGuid,\r
54 (VOID **)&LoadedImage\r
55 );\r
166152e8 56\r
57 ASSERT_EFI_ERROR (Status);\r
58\r
d7b96017
SZ
59 //\r
60 // The LoadedImage->DeviceHandle may be NULL.\r
61 // For example for DxeCore, there is LoadedImage protocol installed for it, but the\r
62 // LoadedImage->DeviceHandle could not be initialized before the FV2 (contain DxeCore)\r
63 // protocol is installed.\r
64 //\r
166152e8 65 return LoadedImage->DeviceHandle;\r
166152e8 66}\r
67\r
68/**\r
9095d37b 69 Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware\r
b75a165d
LG
70 Section type and instance number from the specified Firmware Volume.\r
71\r
9095d37b 72 This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to\r
c1d8b697 73 carry out the Firmware Volume read operation. The function then reads the Firmware Section found specified\r
9095d37b
LG
74 by NameGuid, SectionType and SectionInstance.\r
75\r
76 The details of this search order is defined in description of EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection ()\r
b75a165d 77 found in PI Specification.\r
9095d37b
LG
78\r
79 If SectionType is EFI_SECTION_TE, EFI_SECTION_TE is used as section type to start the search. If EFI_SECTION_TE section\r
80 is not found, EFI_SECTION_PE32 will be used to try the search again. If no EFI_SECTION_PE32 section is found, EFI_NOT_FOUND\r
b75a165d 81 is returned.\r
9095d37b
LG
82\r
83 The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated\r
b75a165d 84 by this function. This function can be only called at TPL_NOTIFY and below.\r
9095d37b 85\r
b75a165d
LG
86 If NameGuid is NULL, then ASSERT();\r
87 If Buffer is NULL, then ASSERT();\r
88 If Size is NULL, then ASSERT().\r
89\r
9095d37b 90 @param FvHandle The device handle that contains a instance of\r
58380e9c 91 EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
b75a165d
LG
92 @param NameGuid The GUID name of a Firmware File.\r
93 @param SectionType The Firmware Section type.\r
9095d37b 94 @param SectionInstance The instance number of Firmware Section to\r
58380e9c 95 read from starting from 0.\r
c1d8b697 96 @param Buffer On output, Buffer contains the data read\r
58380e9c 97 from the section in the Firmware File found.\r
b75a165d
LG
98 @param Size On output, the size of Buffer.\r
99\r
100 @retval EFI_SUCCESS The image is found and data and size is returned.\r
9095d37b 101 @retval EFI_NOT_FOUND The image specified by NameGuid and SectionType\r
58380e9c 102 can't be found.\r
9095d37b 103 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the\r
58380e9c 104 output data buffer or complete the operations.\r
9095d37b 105 @retval EFI_DEVICE_ERROR A hardware error occurs during reading from the\r
58380e9c 106 Firmware Volume.\r
9095d37b 107 @retval EFI_ACCESS_DENIED The firmware volume containing the searched\r
58380e9c 108 Firmware File is configured to disallow reads.\r
9095d37b 109\r
f80b0830 110**/\r
1c280088 111EFI_STATUS\r
eb9dd4d0 112InternalGetSectionFromFv (\r
2f88bd3a
MK
113 IN EFI_HANDLE FvHandle,\r
114 IN CONST EFI_GUID *NameGuid,\r
115 IN EFI_SECTION_TYPE SectionType,\r
116 IN UINTN SectionInstance,\r
117 OUT VOID **Buffer,\r
118 OUT UINTN *Size\r
1c280088 119 )\r
120{\r
2f88bd3a
MK
121 EFI_STATUS Status;\r
122 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
123 UINT32 AuthenticationStatus;\r
166152e8 124\r
8cf43dd7 125 ASSERT (NameGuid != NULL);\r
126 ASSERT (Buffer != NULL);\r
127 ASSERT (Size != NULL);\r
9095d37b 128\r
d7b96017
SZ
129 if (FvHandle == NULL) {\r
130 //\r
131 // Return EFI_NOT_FOUND directly for NULL FvHandle.\r
132 //\r
133 return EFI_NOT_FOUND;\r
134 }\r
166152e8 135\r
136 Status = gBS->HandleProtocol (\r
137 FvHandle,\r
138 &gEfiFirmwareVolume2ProtocolGuid,\r
2f88bd3a 139 (VOID **)&Fv\r
166152e8 140 );\r
141 if (EFI_ERROR (Status)) {\r
7ca066f9 142 return EFI_NOT_FOUND;\r
166152e8 143 }\r
1c280088 144\r
145 //\r
146 // Read desired section content in NameGuid file\r
147 //\r
2f88bd3a
MK
148 *Buffer = NULL;\r
149 *Size = 0;\r
150 Status = Fv->ReadSection (\r
151 Fv,\r
152 NameGuid,\r
153 SectionType,\r
154 SectionInstance,\r
155 Buffer,\r
156 Size,\r
157 &AuthenticationStatus\r
158 );\r
1c280088 159\r
160 if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
161 //\r
9095d37b 162 // Try reading PE32 section, if the required section is TE type\r
1c280088 163 //\r
164 *Buffer = NULL;\r
165 *Size = 0;\r
166 Status = Fv->ReadSection (\r
167 Fv,\r
168 NameGuid,\r
169 EFI_SECTION_PE32,\r
ff197efb 170 SectionInstance,\r
1c280088 171 Buffer,\r
172 Size,\r
173 &AuthenticationStatus\r
174 );\r
175 }\r
176\r
1c280088 177 return Status;\r
178}\r
179\r
682cee4c 180/**\r
9095d37b 181 Searches all the available firmware volumes and returns the first matching FFS section.\r
682cee4c
LG
182\r
183 This function searches all the firmware volumes for FFS files with FV file type specified by FileType\r
9095d37b
LG
184 The order that the firmware volumes is searched is not deterministic. For each available FV a search\r
185 is made for FFS file of type FileType. If the FV contains more than one FFS file with the same FileType,\r
186 the FileInstance instance will be the matched FFS file. For each FFS file found a search\r
187 is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances\r
188 of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.\r
189 Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.\r
190 It is the caller's responsibility to use FreePool() to free the allocated buffer.\r
191 See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections\r
682cee4c
LG
192 are retrieved from an FFS file based on SectionType and SectionInstance.\r
193\r
9095d37b 194 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,\r
682cee4c
LG
195 the search will be retried with a section type of EFI_SECTION_PE32.\r
196 This function must be called with a TPL <= TPL_NOTIFY.\r
197\r
198 If Buffer is NULL, then ASSERT().\r
199 If Size is NULL, then ASSERT().\r
200\r
9095d37b 201 @param FileType Indicates the FV file type to search for within all\r
58380e9c 202 available FVs.\r
9095d37b 203 @param FileInstance Indicates which file instance within all available\r
58380e9c 204 FVs specified by FileType.\r
682cee4c 205 FileInstance starts from zero.\r
9095d37b
LG
206 @param SectionType Indicates the FFS section type to search for\r
207 within the FFS file\r
682cee4c 208 specified by FileType with FileInstance.\r
9095d37b
LG
209 @param SectionInstance Indicates which section instance within the FFS file\r
210 specified by FileType with FileInstance to retrieve.\r
58380e9c 211 SectionInstance starts from zero.\r
9095d37b 212 @param Buffer On output, a pointer to a callee allocated buffer\r
58380e9c 213 containing the FFS file section that was found.\r
9095d37b 214 Is it the caller's responsibility to free this\r
58380e9c 215 buffer using FreePool().\r
682cee4c
LG
216 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
217\r
218 @retval EFI_SUCCESS The specified FFS section was returned.\r
219 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
9095d37b 220 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve\r
58380e9c 221 the matching FFS section.\r
9095d37b 222 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a\r
58380e9c 223 device error.\r
9095d37b
LG
224 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because\r
225 the firmware volume that\r
682cee4c
LG
226 contains the matching FFS section does not allow reads.\r
227**/\r
228EFI_STATUS\r
229EFIAPI\r
230GetSectionFromAnyFvByFileType (\r
2f88bd3a
MK
231 IN EFI_FV_FILETYPE FileType,\r
232 IN UINTN FileInstance,\r
233 IN EFI_SECTION_TYPE SectionType,\r
234 IN UINTN SectionInstance,\r
235 OUT VOID **Buffer,\r
236 OUT UINTN *Size\r
682cee4c
LG
237 )\r
238{\r
2f88bd3a
MK
239 EFI_STATUS Status;\r
240 EFI_HANDLE *HandleBuffer;\r
241 UINTN HandleCount;\r
242 UINTN IndexFv;\r
243 UINTN IndexFile;\r
244 UINTN Key;\r
245 EFI_GUID NameGuid;\r
246 EFI_FV_FILE_ATTRIBUTES Attributes;\r
247 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
682cee4c 248\r
59222fe9
DB
249 ASSERT (Buffer != NULL);\r
250 ASSERT (Size != NULL);\r
251\r
682cee4c
LG
252 //\r
253 // Locate all available FVs.\r
254 //\r
255 HandleBuffer = NULL;\r
2f88bd3a
MK
256 Status = gBS->LocateHandleBuffer (\r
257 ByProtocol,\r
258 &gEfiFirmwareVolume2ProtocolGuid,\r
259 NULL,\r
260 &HandleCount,\r
261 &HandleBuffer\r
262 );\r
682cee4c
LG
263 if (EFI_ERROR (Status)) {\r
264 return Status;\r
265 }\r
266\r
267 //\r
268 // Go through FVs one by one to find the required section data.\r
269 //\r
270 for (IndexFv = 0; IndexFv < HandleCount; IndexFv++) {\r
271 Status = gBS->HandleProtocol (\r
272 HandleBuffer[IndexFv],\r
273 &gEfiFirmwareVolume2ProtocolGuid,\r
274 (VOID **)&Fv\r
275 );\r
276 if (EFI_ERROR (Status)) {\r
277 continue;\r
278 }\r
279\r
280 //\r
281 // Use Firmware Volume 2 Protocol to search for a file of type FileType in all FVs.\r
282 //\r
283 IndexFile = FileInstance + 1;\r
2f88bd3a 284 Key = 0;\r
682cee4c
LG
285 do {\r
286 Status = Fv->GetNextFile (Fv, &Key, &FileType, &NameGuid, &Attributes, Size);\r
287 if (EFI_ERROR (Status)) {\r
288 break;\r
289 }\r
2f88bd3a
MK
290\r
291 IndexFile--;\r
682cee4c 292 } while (IndexFile > 0);\r
b0d803fe 293\r
682cee4c
LG
294 //\r
295 // Fv File with the required FV file type is found.\r
296 // Search the section file in the found FV file.\r
297 //\r
298 if (IndexFile == 0) {\r
299 Status = InternalGetSectionFromFv (\r
9095d37b 300 HandleBuffer[IndexFv],\r
682cee4c
LG
301 &NameGuid,\r
302 SectionType,\r
303 SectionInstance,\r
304 Buffer,\r
305 Size\r
306 );\r
307\r
308 if (!EFI_ERROR (Status)) {\r
309 goto Done;\r
310 }\r
311 }\r
312 }\r
313\r
314 //\r
9095d37b 315 // The required FFS section file is not found.\r
682cee4c
LG
316 //\r
317 if (IndexFv == HandleCount) {\r
318 Status = EFI_NOT_FOUND;\r
319 }\r
320\r
321Done:\r
9095d37b 322 if (HandleBuffer != NULL) {\r
2f88bd3a 323 FreePool (HandleBuffer);\r
682cee4c
LG
324 }\r
325\r
326 return Status;\r
327}\r
b0d803fe 328\r
f80b0830 329/**\r
9095d37b
LG
330 Searches all the availables firmware volumes and returns the first matching FFS section.\r
331\r
332 This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.\r
333 The order that the firmware volumes is searched is not deterministic. For each FFS file found a search\r
334 is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances\r
335 of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.\r
336 Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.\r
337 It is the caller's responsibility to use FreePool() to free the allocated buffer.\r
338 See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections\r
b75a165d
LG
339 are retrieved from an FFS file based on SectionType and SectionInstance.\r
340\r
9095d37b 341 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,\r
b75a165d
LG
342 the search will be retried with a section type of EFI_SECTION_PE32.\r
343 This function must be called with a TPL <= TPL_NOTIFY.\r
344\r
345 If NameGuid is NULL, then ASSERT().\r
346 If Buffer is NULL, then ASSERT().\r
ff197efb 347 If Size is NULL, then ASSERT().\r
348\r
f80b0830 349\r
9095d37b
LG
350 @param NameGuid A pointer to to the FFS filename GUID to search for\r
351 within any of the firmware volumes in the platform.\r
352 @param SectionType Indicates the FFS section type to search for within\r
58380e9c 353 the FFS file specified by NameGuid.\r
9095d37b 354 @param SectionInstance Indicates which section instance within the FFS file\r
58380e9c 355 specified by NameGuid to retrieve.\r
9095d37b
LG
356 @param Buffer On output, a pointer to a callee allocated buffer\r
357 containing the FFS file section that was found.\r
358 Is it the caller's responsibility to free this buffer\r
58380e9c 359 using FreePool().\r
b75a165d
LG
360 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
361\r
362 @retval EFI_SUCCESS The specified FFS section was returned.\r
363 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
9095d37b 364 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to\r
58380e9c 365 retrieve the matching FFS section.\r
9095d37b 366 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a\r
58380e9c 367 device error.\r
9095d37b
LG
368 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the\r
369 firmware volume that\r
b75a165d 370 contains the matching FFS section does not allow reads.\r
f80b0830 371**/\r
b0d803fe 372EFI_STATUS\r
373EFIAPI\r
eb9dd4d0 374GetSectionFromAnyFv (\r
2f88bd3a
MK
375 IN CONST EFI_GUID *NameGuid,\r
376 IN EFI_SECTION_TYPE SectionType,\r
377 IN UINTN SectionInstance,\r
378 OUT VOID **Buffer,\r
379 OUT UINTN *Size\r
b0d803fe 380 )\r
381{\r
2f88bd3a
MK
382 EFI_STATUS Status;\r
383 EFI_HANDLE *HandleBuffer;\r
384 UINTN HandleCount;\r
385 UINTN Index;\r
386 EFI_HANDLE FvHandle;\r
b0d803fe 387\r
388 //\r
389 // Search the FV that contain the caller's FFS first.\r
390 // FV builder can choose to build FFS into the this FV\r
391 // so that this implementation of GetSectionFromAnyFv\r
392 // will locate the FFS faster.\r
393 //\r
166152e8 394 FvHandle = InternalImageHandleToFvHandle (gImageHandle);\r
2f88bd3a
MK
395 Status = InternalGetSectionFromFv (\r
396 FvHandle,\r
397 NameGuid,\r
398 SectionType,\r
399 SectionInstance,\r
400 Buffer,\r
401 Size\r
402 );\r
b0d803fe 403 if (!EFI_ERROR (Status)) {\r
404 return EFI_SUCCESS;\r
405 }\r
406\r
b0d803fe 407 HandleBuffer = NULL;\r
2f88bd3a
MK
408 Status = gBS->LocateHandleBuffer (\r
409 ByProtocol,\r
410 &gEfiFirmwareVolume2ProtocolGuid,\r
411 NULL,\r
412 &HandleCount,\r
413 &HandleBuffer\r
414 );\r
b0d803fe 415 if (EFI_ERROR (Status)) {\r
416 goto Done;\r
417 }\r
418\r
ff197efb 419 for (Index = 0; Index < HandleCount; Index++) {\r
b0d803fe 420 //\r
421 // Skip the FV that contain the caller's FFS\r
422 //\r
ff197efb 423 if (HandleBuffer[Index] != FvHandle) {\r
eb9dd4d0 424 Status = InternalGetSectionFromFv (\r
9095d37b
LG
425 HandleBuffer[Index],\r
426 NameGuid,\r
427 SectionType,\r
ff197efb 428 SectionInstance,\r
9095d37b 429 Buffer,\r
ff197efb 430 Size\r
431 );\r
432\r
433 if (!EFI_ERROR (Status)) {\r
434 goto Done;\r
435 }\r
b0d803fe 436 }\r
b0d803fe 437 }\r
438\r
439 if (Index == HandleCount) {\r
440 Status = EFI_NOT_FOUND;\r
441 }\r
442\r
443Done:\r
9095d37b
LG
444\r
445 if (HandleBuffer != NULL) {\r
2f88bd3a 446 FreePool (HandleBuffer);\r
b0d803fe 447 }\r
9095d37b 448\r
2f88bd3a 449 return Status;\r
b0d803fe 450}\r
451\r
f80b0830 452/**\r
9095d37b 453 Searches the firmware volume that the currently executing module was loaded from and returns the first matching FFS section.\r
b75a165d 454\r
9095d37b
LG
455 This function searches the firmware volume that the currently executing module was loaded\r
456 from for an FFS file with an FFS filename specified by NameGuid. If the FFS file is found a search\r
457 is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance\r
b75a165d 458 instances of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.\r
9095d37b
LG
459 Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.\r
460 It is the caller's responsibility to use FreePool() to free the allocated buffer.\r
461 See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from\r
b75a165d
LG
462 an FFS file based on SectionType and SectionInstance.\r
463\r
464 If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned.\r
9095d37b 465 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,\r
b75a165d 466 the search will be retried with a section type of EFI_SECTION_PE32.\r
9095d37b 467\r
b75a165d
LG
468 This function must be called with a TPL <= TPL_NOTIFY.\r
469 If NameGuid is NULL, then ASSERT().\r
470 If Buffer is NULL, then ASSERT().\r
ff197efb 471 If Size is NULL, then ASSERT().\r
472\r
9095d37b
LG
473 @param NameGuid A pointer to to the FFS filename GUID to search for\r
474 within the firmware volumes that the currently\r
58380e9c 475 executing module was loaded from.\r
9095d37b 476 @param SectionType Indicates the FFS section type to search for within\r
58380e9c 477 the FFS file specified by NameGuid.\r
9095d37b 478 @param SectionInstance Indicates which section instance within the FFS file\r
58380e9c 479 specified by NameGuid to retrieve.\r
9095d37b
LG
480 @param Buffer On output, a pointer to a callee allocated buffer\r
481 containing the FFS file section that was found.\r
482 Is it the caller's responsibility to free this buffer\r
58380e9c 483 using FreePool().\r
b75a165d
LG
484 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
485\r
486\r
487 @retval EFI_SUCCESS The specified FFS section was returned.\r
488 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
9095d37b 489 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve\r
58380e9c 490 the matching FFS section.\r
9095d37b 491 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a\r
58380e9c 492 device error.\r
9095d37b
LG
493 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the\r
494 firmware volume that contains the matching FFS\r
495 section does not allow reads.\r
f80b0830 496**/\r
b0d803fe 497EFI_STATUS\r
498EFIAPI\r
eb9dd4d0 499GetSectionFromFv (\r
2f88bd3a
MK
500 IN CONST EFI_GUID *NameGuid,\r
501 IN EFI_SECTION_TYPE SectionType,\r
502 IN UINTN SectionInstance,\r
503 OUT VOID **Buffer,\r
504 OUT UINTN *Size\r
505 )\r
b0d803fe 506{\r
eb9dd4d0 507 return InternalGetSectionFromFv (\r
2f88bd3a 508 InternalImageHandleToFvHandle (gImageHandle),\r
eb9dd4d0 509 NameGuid,\r
510 SectionType,\r
511 SectionInstance,\r
512 Buffer,\r
513 Size\r
514 );\r
b0d803fe 515}\r
516\r
f80b0830 517/**\r
c1d8b697 518 Searches the FFS file the currently executing module was loaded from and returns the first matching FFS section.\r
b75a165d
LG
519\r
520 This function searches the FFS file that the currently executing module was loaded from for a FFS sections of type SectionType.\r
9095d37b
LG
521 If the FFS file contains at least SectionInstance instances of the FFS section specified by SectionType,\r
522 then the SectionInstance instance is returned in Buffer. Buffer is allocated using AllocatePool(),\r
523 and the size of the allocated buffer is returned in Size. It is the caller's responsibility\r
524 to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for\r
b75a165d
LG
525 details on how sections are retrieved from an FFS file based on SectionType and SectionInstance.\r
526\r
527 If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned.\r
9095d37b 528 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,\r
b75a165d
LG
529 the search will be retried with a section type of EFI_SECTION_PE32.\r
530 This function must be called with a TPL <= TPL_NOTIFY.\r
9095d37b 531\r
b75a165d 532 If Buffer is NULL, then ASSERT().\r
ff197efb 533 If Size is NULL, then ASSERT().\r
534\r
b75a165d 535\r
9095d37b
LG
536 @param SectionType Indicates the FFS section type to search for within\r
537 the FFS file that the currently executing module\r
58380e9c 538 was loaded from.\r
9095d37b
LG
539 @param SectionInstance Indicates which section instance to retrieve within\r
540 the FFS file that the currently executing module\r
58380e9c 541 was loaded from.\r
9095d37b
LG
542 @param Buffer On output, a pointer to a callee allocated buffer\r
543 containing the FFS file section that was found.\r
544 Is it the caller's responsibility to free this buffer\r
58380e9c 545 using FreePool().\r
b75a165d
LG
546 @param Size On output, a pointer to the size, in bytes, of Buffer.\r
547\r
548 @retval EFI_SUCCESS The specified FFS section was returned.\r
549 @retval EFI_NOT_FOUND The specified FFS section could not be found.\r
9095d37b 550 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve\r
58380e9c 551 the matching FFS section.\r
9095d37b 552 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a\r
58380e9c 553 device error.\r
9095d37b
LG
554 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the\r
555 firmware volume that contains the matching FFS\r
556 section does not allow reads.\r
557\r
f80b0830 558**/\r
b0d803fe 559EFI_STATUS\r
560EFIAPI\r
eb9dd4d0 561GetSectionFromFfs (\r
2f88bd3a
MK
562 IN EFI_SECTION_TYPE SectionType,\r
563 IN UINTN SectionInstance,\r
564 OUT VOID **Buffer,\r
565 OUT UINTN *Size\r
566 )\r
b0d803fe 567{\r
2f88bd3a
MK
568 return InternalGetSectionFromFv (\r
569 InternalImageHandleToFvHandle (gImageHandle),\r
eb9dd4d0 570 &gEfiCallerIdGuid,\r
571 SectionType,\r
572 SectionInstance,\r
573 Buffer,\r
574 Size\r
575 );\r
b0d803fe 576}\r
577\r
84716614 578/**\r
9095d37b
LG
579 Get the image file buffer data and buffer size by its device path.\r
580\r
581 Access the file either from a firmware volume, from a file system interface,\r
84716614 582 or from the load file interface.\r
9095d37b 583\r
84716614
LG
584 Allocate memory to store the found image. The caller is responsible to free memory.\r
585\r
3556c7a2 586 If FilePath is NULL, then NULL is returned.\r
84716614
LG
587 If FileSize is NULL, then NULL is returned.\r
588 If AuthenticationStatus is NULL, then NULL is returned.\r
589\r
9095d37b
LG
590 @param[in] BootPolicy Policy for Open Image File.If TRUE, indicates\r
591 that the request originates from the boot\r
58380e9c 592 manager, and that the boot manager is\r
593 attempting to load FilePath as a boot\r
9095d37b 594 selection. If FALSE, then FilePath must\r
58380e9c 595 match an exact file to be loaded.\r
596 @param[in] FilePath The pointer to the device path of the file\r
c1d8b697 597 that is abstracted to the file buffer.\r
9095d37b 598 @param[out] FileSize The pointer to the size of the abstracted\r
58380e9c 599 file buffer.\r
3556c7a2 600 @param[out] AuthenticationStatus Pointer to the authentication status.\r
58380e9c 601\r
3556c7a2 602 @retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationStatus is NULL, or the file can't be found.\r
84716614
LG
603 @retval other The abstracted file buffer. The caller is responsible to free memory.\r
604**/\r
605VOID *\r
606EFIAPI\r
607GetFileBufferByFilePath (\r
2f88bd3a
MK
608 IN BOOLEAN BootPolicy,\r
609 IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
610 OUT UINTN *FileSize,\r
611 OUT UINT32 *AuthenticationStatus\r
84716614
LG
612 )\r
613{\r
2f88bd3a
MK
614 EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
615 EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;\r
616 EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode;\r
617 EFI_HANDLE Handle;\r
618 EFI_GUID *FvNameGuid;\r
619 EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;\r
620 EFI_SECTION_TYPE SectionType;\r
621 UINT8 *ImageBuffer;\r
622 UINTN ImageBufferSize;\r
623 EFI_FV_FILETYPE Type;\r
624 EFI_FV_FILE_ATTRIBUTES Attrib;\r
625 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;\r
626 EFI_FILE_HANDLE FileHandle;\r
627 EFI_FILE_HANDLE LastHandle;\r
628 EFI_FILE_INFO *FileInfo;\r
629 UINTN FileInfoSize;\r
630 EFI_LOAD_FILE_PROTOCOL *LoadFile;\r
631 EFI_LOAD_FILE2_PROTOCOL *LoadFile2;\r
632 EFI_STATUS Status;\r
84716614
LG
633\r
634 //\r
635 // Check input File device path.\r
636 //\r
2f88bd3a 637 if ((FilePath == NULL) || (FileSize == NULL) || (AuthenticationStatus == NULL)) {\r
84716614
LG
638 return NULL;\r
639 }\r
640\r
641 //\r
642 // Init local variable\r
643 //\r
2f88bd3a
MK
644 TempDevicePathNode = NULL;\r
645 FvNameGuid = NULL;\r
646 FileInfo = NULL;\r
647 FileHandle = NULL;\r
648 ImageBuffer = NULL;\r
649 ImageBufferSize = 0;\r
84716614 650 *AuthenticationStatus = 0;\r
9095d37b 651\r
84716614
LG
652 //\r
653 // Copy File Device Path\r
654 //\r
655 OrigDevicePathNode = DuplicateDevicePath (FilePath);\r
656 if (OrigDevicePathNode == NULL) {\r
657 return NULL;\r
658 }\r
659\r
660 //\r
661 // Check whether this device path support FV2 protocol.\r
662 // Is so, this device path may contain a Image.\r
663 //\r
664 DevicePathNode = OrigDevicePathNode;\r
2f88bd3a 665 Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);\r
84716614
LG
666 if (!EFI_ERROR (Status)) {\r
667 //\r
668 // For FwVol File system there is only a single file name that is a GUID.\r
669 //\r
2f88bd3a 670 FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevicePathNode);\r
84716614
LG
671 if (FvNameGuid == NULL) {\r
672 Status = EFI_INVALID_PARAMETER;\r
673 } else {\r
674 //\r
675 // Read image from the firmware file\r
676 //\r
2f88bd3a 677 Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FwVol);\r
84716614
LG
678 if (!EFI_ERROR (Status)) {\r
679 SectionType = EFI_SECTION_PE32;\r
680 ImageBuffer = NULL;\r
2f88bd3a
MK
681 Status = FwVol->ReadSection (\r
682 FwVol,\r
683 FvNameGuid,\r
684 SectionType,\r
685 0,\r
686 (VOID **)&ImageBuffer,\r
687 &ImageBufferSize,\r
688 AuthenticationStatus\r
689 );\r
84716614
LG
690 if (EFI_ERROR (Status)) {\r
691 //\r
692 // Try a raw file, since a PE32 SECTION does not exist\r
693 //\r
694 if (ImageBuffer != NULL) {\r
695 FreePool (ImageBuffer);\r
696 *AuthenticationStatus = 0;\r
697 }\r
2f88bd3a 698\r
84716614 699 ImageBuffer = NULL;\r
2f88bd3a
MK
700 Status = FwVol->ReadFile (\r
701 FwVol,\r
702 FvNameGuid,\r
703 (VOID **)&ImageBuffer,\r
704 &ImageBufferSize,\r
705 &Type,\r
706 &Attrib,\r
707 AuthenticationStatus\r
708 );\r
84716614
LG
709 }\r
710 }\r
711 }\r
2f88bd3a 712\r
c119933d 713 if (!EFI_ERROR (Status)) {\r
714 goto Finish;\r
715 }\r
84716614
LG
716 }\r
717\r
718 //\r
719 // Attempt to access the file via a file system interface\r
720 //\r
721 DevicePathNode = OrigDevicePathNode;\r
2f88bd3a 722 Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);\r
84716614 723 if (!EFI_ERROR (Status)) {\r
2f88bd3a 724 Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Volume);\r
84716614
LG
725 if (!EFI_ERROR (Status)) {\r
726 //\r
727 // Open the Volume to get the File System handle\r
728 //\r
729 Status = Volume->OpenVolume (Volume, &FileHandle);\r
730 if (!EFI_ERROR (Status)) {\r
95dd343a
LG
731 //\r
732 // Duplicate the device path to avoid the access to unaligned device path node.\r
733 // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH\r
734 // nodes, It assures the fields in device path nodes are 2 byte aligned.\r
735 //\r
736 TempDevicePathNode = DuplicateDevicePath (DevicePathNode);\r
737 if (TempDevicePathNode == NULL) {\r
738 FileHandle->Close (FileHandle);\r
c119933d 739 //\r
740 // Setting Status to an EFI_ERROR value will cause the rest of\r
741 // the file system support below to be skipped.\r
742 //\r
95dd343a 743 Status = EFI_OUT_OF_RESOURCES;\r
95dd343a 744 }\r
2f88bd3a 745\r
84716614
LG
746 //\r
747 // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the\r
c1d8b697 748 // directory information and filename can be separate. The goal is to inch\r
84716614
LG
749 // our way down each device path node and close the previous node\r
750 //\r
95dd343a 751 DevicePathNode = TempDevicePathNode;\r
c119933d 752 while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {\r
2f88bd3a
MK
753 if ((DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH) ||\r
754 (DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP))\r
755 {\r
84716614
LG
756 Status = EFI_UNSUPPORTED;\r
757 break;\r
758 }\r
9095d37b 759\r
84716614
LG
760 LastHandle = FileHandle;\r
761 FileHandle = NULL;\r
9095d37b 762\r
84716614 763 Status = LastHandle->Open (\r
2f88bd3a
MK
764 LastHandle,\r
765 &FileHandle,\r
766 ((FILEPATH_DEVICE_PATH *)DevicePathNode)->PathName,\r
767 EFI_FILE_MODE_READ,\r
768 0\r
769 );\r
9095d37b 770\r
84716614
LG
771 //\r
772 // Close the previous node\r
773 //\r
774 LastHandle->Close (LastHandle);\r
9095d37b 775\r
84716614
LG
776 DevicePathNode = NextDevicePathNode (DevicePathNode);\r
777 }\r
9095d37b 778\r
84716614
LG
779 if (!EFI_ERROR (Status)) {\r
780 //\r
781 // We have found the file. Now we need to read it. Before we can read the file we need to\r
782 // figure out how big the file is.\r
783 //\r
2f88bd3a 784 FileInfo = NULL;\r
84716614 785 FileInfoSize = 0;\r
2f88bd3a
MK
786 Status = FileHandle->GetInfo (\r
787 FileHandle,\r
788 &gEfiFileInfoGuid,\r
789 &FileInfoSize,\r
790 FileInfo\r
791 );\r
9095d37b 792\r
84716614
LG
793 if (Status == EFI_BUFFER_TOO_SMALL) {\r
794 FileInfo = AllocatePool (FileInfoSize);\r
795 if (FileInfo == NULL) {\r
796 Status = EFI_OUT_OF_RESOURCES;\r
797 } else {\r
798 Status = FileHandle->GetInfo (\r
2f88bd3a
MK
799 FileHandle,\r
800 &gEfiFileInfoGuid,\r
801 &FileInfoSize,\r
802 FileInfo\r
803 );\r
84716614
LG
804 }\r
805 }\r
9095d37b 806\r
e191bb14 807 if (!EFI_ERROR (Status) && (FileInfo != NULL)) {\r
93e8630a 808 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {\r
84716614 809 //\r
93e8630a 810 // Allocate space for the file\r
84716614 811 //\r
93e8630a
RN
812 ImageBuffer = AllocatePool ((UINTN)FileInfo->FileSize);\r
813 if (ImageBuffer == NULL) {\r
814 Status = EFI_OUT_OF_RESOURCES;\r
815 } else {\r
816 //\r
817 // Read the file into the buffer we allocated\r
818 //\r
819 ImageBufferSize = (UINTN)FileInfo->FileSize;\r
820 Status = FileHandle->Read (FileHandle, &ImageBufferSize, ImageBuffer);\r
821 }\r
84716614
LG
822 }\r
823 }\r
824 }\r
2f88bd3a 825\r
84716614 826 //\r
95dd343a 827 // Close the file and Free FileInfo and TempDevicePathNode since we are done\r
9095d37b 828 //\r
84716614
LG
829 if (FileInfo != NULL) {\r
830 FreePool (FileInfo);\r
831 }\r
2f88bd3a 832\r
84716614
LG
833 if (FileHandle != NULL) {\r
834 FileHandle->Close (FileHandle);\r
835 }\r
2f88bd3a 836\r
c119933d 837 if (TempDevicePathNode != NULL) {\r
838 FreePool (TempDevicePathNode);\r
839 }\r
84716614
LG
840 }\r
841 }\r
2f88bd3a 842\r
c119933d 843 if (!EFI_ERROR (Status)) {\r
844 goto Finish;\r
845 }\r
84716614
LG
846 }\r
847\r
848 //\r
849 // Attempt to access the file via LoadFile2 interface\r
850 //\r
851 if (!BootPolicy) {\r
852 DevicePathNode = OrigDevicePathNode;\r
2f88bd3a 853 Status = gBS->LocateDevicePath (&gEfiLoadFile2ProtocolGuid, &DevicePathNode, &Handle);\r
84716614 854 if (!EFI_ERROR (Status)) {\r
2f88bd3a 855 Status = gBS->HandleProtocol (Handle, &gEfiLoadFile2ProtocolGuid, (VOID **)&LoadFile2);\r
84716614
LG
856 if (!EFI_ERROR (Status)) {\r
857 //\r
858 // Call LoadFile2 with the correct buffer size\r
859 //\r
860 ImageBufferSize = 0;\r
861 ImageBuffer = NULL;\r
2f88bd3a
MK
862 Status = LoadFile2->LoadFile (\r
863 LoadFile2,\r
864 DevicePathNode,\r
865 FALSE,\r
866 &ImageBufferSize,\r
867 ImageBuffer\r
868 );\r
84716614
LG
869 if (Status == EFI_BUFFER_TOO_SMALL) {\r
870 ImageBuffer = AllocatePool (ImageBufferSize);\r
871 if (ImageBuffer == NULL) {\r
872 Status = EFI_OUT_OF_RESOURCES;\r
873 } else {\r
874 Status = LoadFile2->LoadFile (\r
2f88bd3a
MK
875 LoadFile2,\r
876 DevicePathNode,\r
877 FALSE,\r
878 &ImageBufferSize,\r
879 ImageBuffer\r
880 );\r
84716614
LG
881 }\r
882 }\r
883 }\r
2f88bd3a 884\r
c119933d 885 if (!EFI_ERROR (Status)) {\r
886 goto Finish;\r
887 }\r
84716614
LG
888 }\r
889 }\r
890\r
891 //\r
892 // Attempt to access the file via LoadFile interface\r
893 //\r
894 DevicePathNode = OrigDevicePathNode;\r
2f88bd3a 895 Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePathNode, &Handle);\r
84716614 896 if (!EFI_ERROR (Status)) {\r
2f88bd3a 897 Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **)&LoadFile);\r
84716614
LG
898 if (!EFI_ERROR (Status)) {\r
899 //\r
900 // Call LoadFile with the correct buffer size\r
901 //\r
902 ImageBufferSize = 0;\r
903 ImageBuffer = NULL;\r
2f88bd3a
MK
904 Status = LoadFile->LoadFile (\r
905 LoadFile,\r
906 DevicePathNode,\r
907 BootPolicy,\r
908 &ImageBufferSize,\r
909 ImageBuffer\r
910 );\r
84716614
LG
911 if (Status == EFI_BUFFER_TOO_SMALL) {\r
912 ImageBuffer = AllocatePool (ImageBufferSize);\r
913 if (ImageBuffer == NULL) {\r
914 Status = EFI_OUT_OF_RESOURCES;\r
915 } else {\r
916 Status = LoadFile->LoadFile (\r
917 LoadFile,\r
918 DevicePathNode,\r
919 BootPolicy,\r
920 &ImageBufferSize,\r
921 ImageBuffer\r
922 );\r
923 }\r
924 }\r
925 }\r
926 }\r
927\r
928Finish:\r
929\r
930 if (EFI_ERROR (Status)) {\r
931 if (ImageBuffer != NULL) {\r
932 FreePool (ImageBuffer);\r
933 ImageBuffer = NULL;\r
934 }\r
2f88bd3a 935\r
84716614
LG
936 *FileSize = 0;\r
937 } else {\r
938 *FileSize = ImageBufferSize;\r
939 }\r
940\r
941 FreePool (OrigDevicePathNode);\r
942\r
943 return ImageBuffer;\r
944}\r
711ef3f6
SC
945\r
946/**\r
947 Searches all the available firmware volumes and returns the file device path of first matching\r
948 FFS section.\r
949\r
950 This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.\r
951 The order that the firmware volumes is searched is not deterministic. For each FFS file found a search\r
952 is made for FFS sections of type SectionType.\r
953\r
954 If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,\r
955 the search will be retried with a section type of EFI_SECTION_PE32.\r
956 This function must be called with a TPL <= TPL_NOTIFY.\r
957\r
958 If NameGuid is NULL, then ASSERT().\r
959\r
960 @param NameGuid A pointer to to the FFS filename GUID to search for\r
961 within any of the firmware volumes in the platform.\r
962 @param SectionType Indicates the FFS section type to search for within\r
963 the FFS file specified by NameGuid.\r
964 @param SectionInstance Indicates which section instance within the FFS file\r
965 specified by NameGuid to retrieve.\r
966 @param FvFileDevicePath Device path for the target FFS\r
967 file.\r
968\r
969 @retval EFI_SUCCESS The specified file device path of FFS section was returned.\r
970 @retval EFI_NOT_FOUND The specified file device path of FFS section could not be found.\r
971 @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a\r
972 device error.\r
973 @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the\r
974 firmware volume that contains the matching FFS section does not\r
975 allow reads.\r
976 @retval EFI_INVALID_PARAMETER FvFileDevicePath is NULL.\r
977\r
978**/\r
979EFI_STATUS\r
980EFIAPI\r
981GetFileDevicePathFromAnyFv (\r
982 IN CONST EFI_GUID *NameGuid,\r
983 IN EFI_SECTION_TYPE SectionType,\r
984 IN UINTN SectionInstance,\r
985 OUT EFI_DEVICE_PATH_PROTOCOL **FvFileDevicePath\r
986 )\r
987{\r
2f88bd3a
MK
988 EFI_STATUS Status;\r
989 EFI_HANDLE *HandleBuffer;\r
990 UINTN HandleCount;\r
991 UINTN Index;\r
992 EFI_HANDLE FvHandle;\r
993 EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;\r
994 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *TempFvFileDevicePath;\r
995 VOID *Buffer;\r
996 UINTN Size;\r
711ef3f6
SC
997\r
998 if (FvFileDevicePath == NULL) {\r
999 return EFI_INVALID_PARAMETER;\r
1000 }\r
1001\r
1002 HandleBuffer = NULL;\r
1003 FvDevicePath = NULL;\r
1004 TempFvFileDevicePath = NULL;\r
1005 Buffer = NULL;\r
1006 Size = 0;\r
1007\r
1008 //\r
1009 // Search the FV that contain the caller's FFS first.\r
1010 // FV builder can choose to build FFS into the this FV\r
1011 // so that this implementation of GetSectionFromAnyFv\r
1012 // will locate the FFS faster.\r
1013 //\r
1014 FvHandle = InternalImageHandleToFvHandle (gImageHandle);\r
2f88bd3a
MK
1015 Status = InternalGetSectionFromFv (\r
1016 FvHandle,\r
1017 NameGuid,\r
1018 SectionType,\r
1019 SectionInstance,\r
1020 &Buffer,\r
1021 &Size\r
1022 );\r
711ef3f6
SC
1023 if (!EFI_ERROR (Status)) {\r
1024 goto Done;\r
1025 }\r
1026\r
1027 Status = gBS->LocateHandleBuffer (\r
1028 ByProtocol,\r
1029 &gEfiFirmwareVolume2ProtocolGuid,\r
1030 NULL,\r
1031 &HandleCount,\r
1032 &HandleBuffer\r
1033 );\r
1034 if (EFI_ERROR (Status)) {\r
1035 goto Done;\r
1036 }\r
1037\r
1038 for (Index = 0; Index < HandleCount; Index++) {\r
1039 //\r
1040 // Skip the FV that contain the caller's FFS\r
1041 //\r
1042 if (HandleBuffer[Index] != FvHandle) {\r
1043 Status = InternalGetSectionFromFv (\r
1044 HandleBuffer[Index],\r
1045 NameGuid,\r
1046 SectionType,\r
1047 SectionInstance,\r
1048 &Buffer,\r
1049 &Size\r
1050 );\r
1051\r
1052 if (!EFI_ERROR (Status)) {\r
1053 //\r
1054 // Update FvHandle to the current handle.\r
1055 //\r
1056 FvHandle = HandleBuffer[Index];\r
1057 goto Done;\r
1058 }\r
1059 }\r
1060 }\r
1061\r
1062 if (Index == HandleCount) {\r
1063 Status = EFI_NOT_FOUND;\r
1064 }\r
1065\r
1066Done:\r
1067 if (Status == EFI_SUCCESS) {\r
1068 //\r
1069 // Build a device path to the file in the FV to pass into gBS->LoadImage\r
1070 //\r
1071 Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);\r
1072 if (EFI_ERROR (Status)) {\r
1073 *FvFileDevicePath = NULL;\r
1074 } else {\r
1075 TempFvFileDevicePath = AllocateZeroPool (sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + END_DEVICE_PATH_LENGTH);\r
1076 if (TempFvFileDevicePath == NULL) {\r
1077 *FvFileDevicePath = NULL;\r
1078 return EFI_OUT_OF_RESOURCES;\r
1079 }\r
2f88bd3a
MK
1080\r
1081 EfiInitializeFwVolDevicepathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempFvFileDevicePath, NameGuid);\r
711ef3f6
SC
1082 SetDevicePathEndNode (NextDevicePathNode (TempFvFileDevicePath));\r
1083 *FvFileDevicePath = AppendDevicePath (\r
1084 FvDevicePath,\r
1085 (EFI_DEVICE_PATH_PROTOCOL *)TempFvFileDevicePath\r
1086 );\r
1087 FreePool (TempFvFileDevicePath);\r
1088 }\r
1089 }\r
1090\r
1091 if (Buffer != NULL) {\r
1092 FreePool (Buffer);\r
1093 }\r
1094\r
1095 if (HandleBuffer != NULL) {\r
1096 FreePool (HandleBuffer);\r
1097 }\r
1098\r
1099 return Status;\r
1100}\r