summaryrefslogtreecommitdiffstats
path: root/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2010-05-05 01:56:41 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2010-05-05 01:56:41 +0000
commit682cee4c06ed1b7961a966135a8be1f92d6c5c89 (patch)
tree2472c28aa01cd9e05808d14b6233d8686f53078c /MdePkg/Library/DxeServicesLib/DxeServicesLib.c
parent2b649f74775d0efd1e75c91f77c3045ae6249cb4 (diff)
downloadedk2-682cee4c06ed1b7961a966135a8be1f92d6c5c89.tar.gz
edk2-682cee4c06ed1b7961a966135a8be1f92d6c5c89.tar.bz2
edk2-682cee4c06ed1b7961a966135a8be1f92d6c5c89.zip
Add new API GetSectionFromAnyFvByFileType() into MdePkg DxeServicesLib.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10456 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdePkg/Library/DxeServicesLib/DxeServicesLib.c')
-rw-r--r--MdePkg/Library/DxeServicesLib/DxeServicesLib.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
index 49c9ad492e..9588008cdc 100644
--- a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
+++ b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
@@ -166,7 +166,141 @@ InternalGetSectionFromFv (
return Status;
}
+/**
+ Searches all the available firmware volumes and returns the first matching FFS section.
+
+ This function searches all the firmware volumes for FFS files with FV file type specified by FileType
+ The order that the firmware volumes is searched is not deterministic. For each available FV a search
+ is made for FFS file of type FileType. If the FV contains more than one FFS file with the same FileType,
+ the FileInstance instance will be the matched FFS file. For each FFS file found a search
+ is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances
+ of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.
+ Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size.
+ It is the caller's responsibility to use FreePool() to free the allocated buffer.
+ See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections
+ are retrieved from an FFS file based on SectionType and SectionInstance.
+
+ If SectionType is EFI_SECTION_TE, and the search with an FFS file fails,
+ the search will be retried with a section type of EFI_SECTION_PE32.
+ This function must be called with a TPL <= TPL_NOTIFY.
+
+ If Buffer is NULL, then ASSERT().
+ If Size is NULL, then ASSERT().
+
+ @param FileType Indicates the FV file type to search for within all available FVs.
+ @param FileInstance Indicates which file instance within all available FVs specified by FileType.
+ FileInstance starts from zero.
+ @param SectionType Indicates the FFS section type to search for within the FFS file
+ specified by FileType with FileInstance.
+ @param SectionInstance Indicates which section instance within the FFS file
+ specified by FileType with FileInstance to retrieve. SectionInstance starts from zero.
+ @param Buffer On output, a pointer to a callee allocated buffer containing the FFS file section that was found.
+ Is it the caller's responsibility to free this buffer using FreePool().
+ @param Size On output, a pointer to the size, in bytes, of Buffer.
+
+ @retval EFI_SUCCESS The specified FFS section was returned.
+ @retval EFI_NOT_FOUND The specified FFS section could not be found.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve the matching FFS section.
+ @retval EFI_DEVICE_ERROR The FFS section could not be retrieves due to a device error.
+ @retval EFI_ACCESS_DENIED The FFS section could not be retrieves because the firmware volume that
+ contains the matching FFS section does not allow reads.
+**/
+EFI_STATUS
+EFIAPI
+GetSectionFromAnyFvByFileType (
+ IN EFI_FV_FILETYPE FileType,
+ IN UINTN FileInstance,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ OUT VOID **Buffer,
+ OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN IndexFv;
+ UINTN IndexFile;
+ UINTN Key;
+ EFI_GUID NameGuid;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+
+ //
+ // Locate all available FVs.
+ //
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Go through FVs one by one to find the required section data.
+ //
+ for (IndexFv = 0; IndexFv < HandleCount; IndexFv++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[IndexFv],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **)&Fv
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ //
+ // Use Firmware Volume 2 Protocol to search for a file of type FileType in all FVs.
+ //
+ IndexFile = FileInstance + 1;
+ Key = 0;
+ do {
+ Status = Fv->GetNextFile (Fv, &Key, &FileType, &NameGuid, &Attributes, Size);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ IndexFile --;
+ } while (IndexFile > 0);
+
+ //
+ // Fv File with the required FV file type is found.
+ // Search the section file in the found FV file.
+ //
+ if (IndexFile == 0) {
+ Status = InternalGetSectionFromFv (
+ HandleBuffer[IndexFv],
+ &NameGuid,
+ SectionType,
+ SectionInstance,
+ Buffer,
+ Size
+ );
+
+ if (!EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+ }
+
+ //
+ // The required FFS section file is not found.
+ //
+ if (IndexFv == HandleCount) {
+ Status = EFI_NOT_FOUND;
+ }
+
+Done:
+ if (HandleBuffer != NULL) {
+ FreePool(HandleBuffer);
+ }
+
+ return Status;
+}
/**
Searches all the availables firmware volumes and returns the first matching FFS section.