3) A support protocol is not found, and the data is not available to be read\r
without it. This results in EFI_PROTOCOL_ERROR.\r
\r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
//\r
UINTN EncapsulatedStreamHandle;\r
EFI_GUID *EncapsulationGuid;\r
+ //\r
+ // If the section REQUIRES an extraction protocol, register for RPN\r
+ // when the required GUIDed extraction protocol becomes available.\r
+ //\r
+ EFI_EVENT Event;\r
} CORE_SECTION_CHILD_NODE;\r
\r
#define CORE_SECTION_STREAM_SIGNATURE SIGNATURE_32('S','X','S','S')\r
CORE_SECTION_CHILD_NODE *ChildNode;\r
CORE_SECTION_STREAM_NODE *ParentStream;\r
VOID *Registration;\r
- EFI_EVENT Event;\r
} RPN_EVENT_CONTEXT;\r
\r
\r
return OpenSectionStreamEx (\r
SectionStreamLength,\r
SectionStream,\r
- TRUE,\r
+ FALSE,\r
0,\r
SectionStreamHandle\r
);\r
}\r
}\r
\r
+/**\r
+ Verify the Guided Section GUID by checking if there is the Guided Section GUID configuration table recorded the GUID itself.\r
+\r
+ @param GuidedSectionGuid The Guided Section GUID.\r
+ @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Protocol\r
+ for the Guided Section.\r
+\r
+ @return TRUE The GuidedSectionGuid could be identified, and the pointer to\r
+ the Guided Section Extraction Protocol will be returned to *GuidedSectionExtraction.\r
+ @return FALSE The GuidedSectionGuid could not be identified, or\r
+ the Guided Section Extraction Protocol has not been installed yet.\r
+\r
+**/\r
+BOOLEAN\r
+VerifyGuidedSectionGuid (\r
+ IN EFI_GUID *GuidedSectionGuid,\r
+ OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL **GuidedSectionExtraction\r
+ )\r
+{\r
+ EFI_GUID *GuidRecorded;\r
+ VOID *Interface;\r
+ EFI_STATUS Status;\r
+\r
+ Interface = NULL;\r
+\r
+ //\r
+ // Check if there is the Guided Section GUID configuration table recorded the GUID itself.\r
+ //\r
+ Status = EfiGetSystemConfigurationTable (GuidedSectionGuid, (VOID **) &GuidRecorded);\r
+ if (Status == EFI_SUCCESS) {\r
+ if (CompareGuid (GuidRecorded, GuidedSectionGuid)) {\r
+ //\r
+ // Found the recorded GuidedSectionGuid.\r
+ //\r
+ Status = CoreLocateProtocol (GuidedSectionGuid, NULL, (VOID **) &Interface);\r
+ if (!EFI_ERROR (Status) && Interface != NULL) {\r
+ //\r
+ // Found the supported Guided Section Extraction Porotocol for the Guided Section.\r
+ //\r
+ *GuidedSectionExtraction = (EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *) Interface;\r
+ return TRUE;\r
+ }\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
RPN callback function. Initializes the section stream\r
when GUIDED_SECTION_EXTRACTION_PROTOCOL is installed.\r
UINTN NewStreamBufferSize;\r
UINT32 AuthenticationStatus;\r
RPN_EVENT_CONTEXT *Context;\r
- \r
+\r
Context = RpnContext;\r
- \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
+\r
+ if (!VerifyGuidedSectionGuid (Context->ChildNode->EncapsulationGuid, &GuidedExtraction)) {\r
return;\r
}\r
- \r
+\r
Status = GuidedExtraction->ExtractSection (\r
GuidedExtraction,\r
GuidedHeader,\r
// Close the event when done.\r
//\r
gBS->CloseEvent (Event);\r
+ Context->ChildNode->Event = NULL;\r
FreePool (Context);\r
-} \r
+}\r
\r
/**\r
Constructor for RPN event when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears...\r
)\r
{\r
RPN_EVENT_CONTEXT *Context;\r
- \r
+\r
//\r
// Allocate new event structure and context\r
//\r
Context = AllocatePool (sizeof (RPN_EVENT_CONTEXT));\r
ASSERT (Context != NULL);\r
- \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
+ Context->ChildNode->Event = EfiCreateProtocolNotifyEvent (\r
+ Context->ChildNode->EncapsulationGuid,\r
+ TPL_NOTIFY,\r
+ NotifyGuidedExtraction,\r
+ Context,\r
+ &Context->Registration\r
+ );\r
}\r
\r
/**\r
CreateChildNode (\r
IN CORE_SECTION_STREAM_NODE *Stream,\r
IN UINT32 ChildOffset,\r
- OUT CORE_SECTION_CHILD_NODE **ChildNode\r
+ OUT CORE_SECTION_CHILD_NODE **ChildNode\r
)\r
{\r
EFI_STATUS Status;\r
//\r
// Allocate a new node\r
//\r
- *ChildNode = AllocatePool (sizeof (CORE_SECTION_CHILD_NODE));\r
+ *ChildNode = AllocateZeroPool (sizeof (CORE_SECTION_CHILD_NODE));\r
Node = *ChildNode;\r
if (Node == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
//\r
// Get the CompressionSectionHeader\r
//\r
- ASSERT (Node->Size >= sizeof (EFI_COMPRESSION_SECTION));\r
+ if (Node->Size < sizeof (EFI_COMPRESSION_SECTION)) {\r
+ CoreFreePool (Node);\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
CompressionHeader = (EFI_COMPRESSION_SECTION *) SectionHeader;\r
\r
(UINT32 *)&NewStreamBufferSize,\r
&ScratchSize\r
);\r
- ASSERT_EFI_ERROR (Status);\r
- ASSERT (NewStreamBufferSize == UncompressedLength);\r
+ if (EFI_ERROR (Status) || (NewStreamBufferSize != UncompressedLength)) {\r
+ CoreFreePool (Node);\r
+ CoreFreePool (NewStreamBuffer);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = EFI_BAD_BUFFER_SIZE;\r
+ }\r
+ return Status;\r
+ }\r
\r
ScratchBuffer = AllocatePool (ScratchSize);\r
if (ScratchBuffer == NULL) {\r
ScratchBuffer,\r
ScratchSize\r
);\r
- ASSERT_EFI_ERROR (Status);\r
CoreFreePool (ScratchBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ CoreFreePool (Node);\r
+ CoreFreePool (NewStreamBuffer);\r
+ return Status;\r
+ }\r
}\r
} else {\r
NewStreamBuffer = NULL;\r
Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid;\r
GuidedSectionAttributes = GuidedHeader->Attributes;\r
}\r
- Status = CoreLocateProtocol (Node->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);\r
- if (!EFI_ERROR (Status) && GuidedExtraction != NULL) {\r
+ if (VerifyGuidedSectionGuid (Node->EncapsulationGuid, &GuidedExtraction)) {\r
//\r
// NewStreamBuffer is always allocated by ExtractSection... No caller\r
// allocation here.\r
//\r
if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {\r
//\r
- // If the section REQUIRES an extraction protocol, register for RPN \r
- // when the required GUIDed extraction protocol becomes available. \r
+ // If the section REQUIRES an extraction protocol, register for RPN\r
+ // when the required GUIDed extraction protocol becomes available.\r
//\r
CreateGuidedExtractionRpnEvent (Stream, Node);\r
} else {\r
//\r
AuthenticationStatus = Stream->AuthenticationStatus;\r
\r
+ if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {\r
+ AuthenticationStatus |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED;\r
+ }\r
+\r
if (IS_SECTION2 (GuidedHeader)) {\r
Status = OpenSectionStreamEx (\r
SECTION2_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset,\r
non-null on input, then the buffer is caller\r
allocated. If Buffer is NULL, then the buffer\r
is callee allocated. In either case, the\r
- requried buffer size is returned in *BufferSize.\r
+ required buffer size is returned in *BufferSize.\r
@param BufferSize On input, indicates the size of *Buffer if\r
*Buffer is non-null on input. On output,\r
indicates the required size (allocated size if\r
EFI_COMMON_SECTION_HEADER *Section;\r
\r
\r
+ ChildStreamNode = NULL;\r
OldTpl = CoreRaiseTpl (TPL_NOTIFY);\r
Instance = SectionInstance + 1;\r
\r
// If it's an encapsulating section, we close the resulting section stream.\r
// CloseSectionStream will free all memory associated with the stream.\r
//\r
- CloseSectionStream (ChildNode->EncapsulatedStreamHandle);\r
+ CloseSectionStream (ChildNode->EncapsulatedStreamHandle, TRUE);\r
+ }\r
+\r
+ if (ChildNode->Event != NULL) {\r
+ gBS->CloseEvent (ChildNode->Event);\r
}\r
+\r
//\r
// Last, free the child node itself\r
//\r
SEP member function. Deletes an existing section stream\r
\r
@param StreamHandleToClose Indicates the stream to close\r
+ @param FreeStreamBuffer TRUE - Need to free stream buffer;\r
+ FALSE - No need to free stream buffer.\r
\r
@retval EFI_SUCCESS The section stream is closed sucessfully.\r
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
EFI_STATUS\r
EFIAPI\r
CloseSectionStream (\r
- IN UINTN StreamHandleToClose\r
+ IN UINTN StreamHandleToClose,\r
+ IN BOOLEAN FreeStreamBuffer\r
)\r
{\r
CORE_SECTION_STREAM_NODE *StreamNode;\r
ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);\r
FreeChildNode (ChildNode);\r
}\r
- CoreFreePool (StreamNode->StreamBuffer);\r
+ if (FreeStreamBuffer) {\r
+ CoreFreePool (StreamNode->StreamBuffer);\r
+ }\r
CoreFreePool (StreamNode);\r
Status = EFI_SUCCESS;\r
} else {\r
//\r
AllocatedOutputBuffer = AllocatePool (OutputBufferSize);\r
if (AllocatedOutputBuffer == NULL) {\r
- FreePool (ScratchBuffer);\r
+ if (ScratchBuffer != NULL) {\r
+ FreePool (ScratchBuffer);\r
+ }\r
return EFI_OUT_OF_RESOURCES;\r
}\r
*OutputBuffer = AllocatedOutputBuffer;\r