return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid);\r
}\r
\r
+/**\r
+ RPN callback function. Initializes the section stream\r
+ when GUIDED_SECTION_EXTRACTION_PROTOCOL is installed.\r
+\r
+ @param Event The event that fired\r
+ @param RpnContext A pointer to the context that allows us to identify\r
+ the relevent encapsulation.\r
+**/\r
+VOID\r
+EFIAPI\r
+NotifyGuidedExtraction (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *RpnContext\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_GUID_DEFINED_SECTION *GuidedHeader;\r
+ EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction;\r
+ VOID *NewStreamBuffer;\r
+ UINTN NewStreamBufferSize;\r
+ UINT32 AuthenticationStatus;\r
+ RPN_EVENT_CONTEXT *Context;\r
+ \r
+ Context = RpnContext;\r
+ \r
+ GuidedHeader = (EFI_GUID_DEFINED_SECTION *) (Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream);\r
+ ASSERT (GuidedHeader->CommonHeader.Type == EFI_SECTION_GUID_DEFINED);\r
+ \r
+ Status = gBS->LocateProtocol (Context->ChildNode->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+ \r
+ Status = GuidedExtraction->ExtractSection (\r
+ GuidedExtraction,\r
+ GuidedHeader,\r
+ &NewStreamBuffer,\r
+ &NewStreamBufferSize,\r
+ &AuthenticationStatus\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Make sure we initialize the new stream with the correct\r
+ // authentication status for both aggregate and local status fields.\r
+ //\r
+ if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) {\r
+ //\r
+ // OR in the parent stream's aggregate status.\r
+ //\r
+ AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AUTH_STATUS_ALL;\r
+ } else {\r
+ //\r
+ // since there's no authentication data contributed by the section,\r
+ // just inherit the full value from our immediate parent.\r
+ //\r
+ AuthenticationStatus = Context->ParentStream->AuthenticationStatus;\r
+ }\r
+\r
+ Status = OpenSectionStreamEx (\r
+ NewStreamBufferSize,\r
+ NewStreamBuffer,\r
+ FALSE,\r
+ AuthenticationStatus,\r
+ &Context->ChildNode->EncapsulatedStreamHandle\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Close the event when done.\r
+ //\r
+ gBS->CloseEvent (Event);\r
+ FreePool (Context);\r
+} \r
+\r
+/**\r
+ Constructor for RPN event when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears...\r
+\r
+ @param ParentStream Indicates the parent of the ecnapsulation section (child)\r
+ @param ChildNode Indicates the child node that is the encapsulation section.\r
+\r
+**/\r
+VOID\r
+CreateGuidedExtractionRpnEvent (\r
+ IN CORE_SECTION_STREAM_NODE *ParentStream,\r
+ IN CORE_SECTION_CHILD_NODE *ChildNode\r
+ )\r
+{\r
+ RPN_EVENT_CONTEXT *Context;\r
+ \r
+ //\r
+ // Allocate new event structure and context\r
+ //\r
+ Context = AllocatePool (sizeof (RPN_EVENT_CONTEXT));\r
+ ASSERT (Context != NULL);\r
+ \r
+ Context->ChildNode = ChildNode;\r
+ Context->ParentStream = ParentStream;\r
+ \r
+ Context->Event = EfiCreateProtocolNotifyEvent (\r
+ Context->ChildNode->EncapsulationGuid,\r
+ TPL_NOTIFY,\r
+ NotifyGuidedExtraction,\r
+ Context,\r
+ &Context->Registration\r
+ );\r
+}\r
\r
/**\r
Worker function. Constructor for new child nodes.\r
//\r
if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {\r
//\r
- // If the section REQUIRES an extraction protocol, then we're toast\r
+ // If the section REQUIRES an extraction protocol, register for RPN \r
+ // when the required GUIDed extraction protocol becomes available. \r
//\r
- CoreFreePool (*ChildNode);\r
- return EFI_PROTOCOL_ERROR;\r
- }\r
-\r
- //\r
- // Figure out the proper authentication status\r
- //\r
- AuthenticationStatus = Stream->AuthenticationStatus;\r
+ CreateGuidedExtractionRpnEvent (Stream, Node);\r
+ } else {\r
+ //\r
+ // Figure out the proper authentication status\r
+ //\r
+ AuthenticationStatus = Stream->AuthenticationStatus;\r
\r
- SectionLength = SECTION_SIZE (GuidedHeader);\r
- Status = OpenSectionStreamEx (\r
- SectionLength - GuidedHeader->DataOffset,\r
- (UINT8 *) GuidedHeader + GuidedHeader->DataOffset,\r
- TRUE,\r
- AuthenticationStatus,\r
- &Node->EncapsulatedStreamHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- CoreFreePool (Node);\r
- return Status;\r
+ SectionLength = SECTION_SIZE (GuidedHeader);\r
+ Status = OpenSectionStreamEx (\r
+ SectionLength - GuidedHeader->DataOffset,\r
+ (UINT8 *) GuidedHeader + GuidedHeader->DataOffset,\r
+ TRUE,\r
+ AuthenticationStatus,\r
+ &Node->EncapsulatedStreamHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ CoreFreePool (Node);\r
+ return Status;\r
+ }\r
}\r
}\r
\r
} else {\r
ErrorStatus = Status;\r
}\r
+ } else if ((CurrentChildNode->Type == EFI_SECTION_GUID_DEFINED) && (SearchType != EFI_SECTION_GUID_DEFINED)) {\r
+ //\r
+ // When Node Type is GUIDED section, but Node has no encapsulated data, Node data should not be parsed\r
+ // because a required GUIDED section extraction protocol does not exist.\r
+ // If SearchType is not GUIDED section, EFI_PROTOCOL_ERROR should return.\r
+ //\r
+ ErrorStatus = EFI_PROTOCOL_ERROR;\r
}\r
\r
if (!IsNodeAtEnd (&SourceStream->Children, &CurrentChildNode->Link)) {\r