From 1d6ee65f82bd30fa5c155509f1a6f2a7372045c5 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Wed, 28 Jul 2010 01:12:18 +0000 Subject: =?UTF-8?q?Enhance=20FV2.ReadSection()=20to=20read=20GUIDED=20sect?= =?UTF-8?q?ion=20raw=20data=20when=20its=20extraction=20guided=20protocol?= =?UTF-8?q?=20doesn=E2=80=99t=20exist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10702 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Dxe/SectionExtraction/CoreSectionExtraction.c | 154 ++++++++++++++++++--- 1 file changed, 134 insertions(+), 20 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c index 6d660ed942..cc129cc008 100644 --- a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c +++ b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c @@ -478,6 +478,113 @@ ChildIsType ( return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid); } +/** + RPN callback function. Initializes the section stream + when GUIDED_SECTION_EXTRACTION_PROTOCOL is installed. + + @param Event The event that fired + @param RpnContext A pointer to the context that allows us to identify + the relevent encapsulation. +**/ +VOID +EFIAPI +NotifyGuidedExtraction ( + IN EFI_EVENT Event, + IN VOID *RpnContext + ) +{ + EFI_STATUS Status; + EFI_GUID_DEFINED_SECTION *GuidedHeader; + EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction; + VOID *NewStreamBuffer; + UINTN NewStreamBufferSize; + UINT32 AuthenticationStatus; + RPN_EVENT_CONTEXT *Context; + + Context = RpnContext; + + GuidedHeader = (EFI_GUID_DEFINED_SECTION *) (Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream); + ASSERT (GuidedHeader->CommonHeader.Type == EFI_SECTION_GUID_DEFINED); + + Status = gBS->LocateProtocol (Context->ChildNode->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction); + if (EFI_ERROR (Status)) { + return; + } + + Status = GuidedExtraction->ExtractSection ( + GuidedExtraction, + GuidedHeader, + &NewStreamBuffer, + &NewStreamBufferSize, + &AuthenticationStatus + ); + ASSERT_EFI_ERROR (Status); + + // + // Make sure we initialize the new stream with the correct + // authentication status for both aggregate and local status fields. + // + if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) { + // + // OR in the parent stream's aggregate status. + // + AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AUTH_STATUS_ALL; + } else { + // + // since there's no authentication data contributed by the section, + // just inherit the full value from our immediate parent. + // + AuthenticationStatus = Context->ParentStream->AuthenticationStatus; + } + + Status = OpenSectionStreamEx ( + NewStreamBufferSize, + NewStreamBuffer, + FALSE, + AuthenticationStatus, + &Context->ChildNode->EncapsulatedStreamHandle + ); + ASSERT_EFI_ERROR (Status); + + // + // Close the event when done. + // + gBS->CloseEvent (Event); + FreePool (Context); +} + +/** + Constructor for RPN event when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears... + + @param ParentStream Indicates the parent of the ecnapsulation section (child) + @param ChildNode Indicates the child node that is the encapsulation section. + +**/ +VOID +CreateGuidedExtractionRpnEvent ( + IN CORE_SECTION_STREAM_NODE *ParentStream, + IN CORE_SECTION_CHILD_NODE *ChildNode + ) +{ + RPN_EVENT_CONTEXT *Context; + + // + // Allocate new event structure and context + // + Context = AllocatePool (sizeof (RPN_EVENT_CONTEXT)); + ASSERT (Context != NULL); + + Context->ChildNode = ChildNode; + Context->ParentStream = ParentStream; + + Context->Event = EfiCreateProtocolNotifyEvent ( + Context->ChildNode->EncapsulationGuid, + TPL_NOTIFY, + NotifyGuidedExtraction, + Context, + &Context->Registration + ); +} /** Worker function. Constructor for new child nodes. @@ -687,28 +794,28 @@ CreateChildNode ( // if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { // - // If the section REQUIRES an extraction protocol, then we're toast + // If the section REQUIRES an extraction protocol, register for RPN + // when the required GUIDed extraction protocol becomes available. // - CoreFreePool (*ChildNode); - return EFI_PROTOCOL_ERROR; - } - - // - // Figure out the proper authentication status - // - AuthenticationStatus = Stream->AuthenticationStatus; + CreateGuidedExtractionRpnEvent (Stream, Node); + } else { + // + // Figure out the proper authentication status + // + AuthenticationStatus = Stream->AuthenticationStatus; - SectionLength = SECTION_SIZE (GuidedHeader); - Status = OpenSectionStreamEx ( - SectionLength - GuidedHeader->DataOffset, - (UINT8 *) GuidedHeader + GuidedHeader->DataOffset, - TRUE, - AuthenticationStatus, - &Node->EncapsulatedStreamHandle - ); - if (EFI_ERROR (Status)) { - CoreFreePool (Node); - return Status; + SectionLength = SECTION_SIZE (GuidedHeader); + Status = OpenSectionStreamEx ( + SectionLength - GuidedHeader->DataOffset, + (UINT8 *) GuidedHeader + GuidedHeader->DataOffset, + TRUE, + AuthenticationStatus, + &Node->EncapsulatedStreamHandle + ); + if (EFI_ERROR (Status)) { + CoreFreePool (Node); + return Status; + } } } @@ -849,6 +956,13 @@ FindChildNode ( } else { ErrorStatus = Status; } + } else if ((CurrentChildNode->Type == EFI_SECTION_GUID_DEFINED) && (SearchType != EFI_SECTION_GUID_DEFINED)) { + // + // When Node Type is GUIDED section, but Node has no encapsulated data, Node data should not be parsed + // because a required GUIDED section extraction protocol does not exist. + // If SearchType is not GUIDED section, EFI_PROTOCOL_ERROR should return. + // + ErrorStatus = EFI_PROTOCOL_ERROR; } if (!IsNodeAtEnd (&SourceStream->Children, &CurrentChildNode->Link)) { -- cgit v1.2.3