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