40#define CORE_SECTION_CHILD_SIGNATURE SIGNATURE_32('S','X','C','S')
41#define CHILD_SECTION_NODE_FROM_LINK(Node) \
42 CR (Node, CORE_SECTION_CHILD_NODE, Link, CORE_SECTION_CHILD_SIGNATURE)
53 UINT32 OffsetInStream;
61 UINTN EncapsulatedStreamHandle;
70#define CORE_SECTION_STREAM_SIGNATURE SIGNATURE_32('S','X','S','S')
71#define STREAM_NODE_FROM_LINK(Node) \
72 CR (Node, CORE_SECTION_STREAM_NODE, Link, CORE_SECTION_STREAM_SIGNATURE)
84 UINT32 AuthenticationStatus;
87#define NULL_STREAM_HANDLE 0
183 OUT VOID **OutputBuffer,
185 OUT UINT32 *AuthenticationStatus
219 UINTN ExtractHandlerNumber;
224 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
230 while (ExtractHandlerNumber-- > 0) {
232 &mSectionExtractionHandle,
233 &ExtractHandlerGuidTable[ExtractHandlerNumber],
235 &mCustomGuidedSectionExtractionProtocol
254 IN VOID *SectionStream,
266 while (TotalLength < SectionStreamLength) {
267 if (IS_SECTION2 (SectionHeader)) {
268 SectionLength = SECTION2_SIZE (SectionHeader);
273 TotalLength += SectionLength;
275 if (TotalLength == SectionStreamLength) {
288 TotalLength += (
UINTN)NextSectionHeader - (
UINTN)SectionHeader;
289 SectionHeader = NextSectionHeader;
332 IN VOID *SectionStream,
333 IN BOOLEAN AllocateBuffer,
334 IN UINT32 AuthenticationStatus,
345 if (NewStream ==
NULL) {
346 return EFI_OUT_OF_RESOURCES;
349 if (AllocateBuffer) {
354 if (SectionStreamLength > 0) {
355 NewStream->StreamBuffer =
AllocatePool (SectionStreamLength);
356 if (NewStream->StreamBuffer ==
NULL) {
358 return EFI_OUT_OF_RESOURCES;
364 CopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength);
369 NewStream->StreamBuffer =
NULL;
377 NewStream->StreamBuffer = SectionStream;
383 NewStream->Signature = CORE_SECTION_STREAM_SIGNATURE;
384 NewStream->StreamHandle = (
UINTN)NewStream;
385 NewStream->StreamLength = SectionStreamLength;
387 NewStream->AuthenticationStatus = AuthenticationStatus;
396 *SectionStreamHandle = NewStream->StreamHandle;
420 IN VOID *SectionStream,
428 return EFI_INVALID_PARAMETER;
459 IN EFI_SECTION_TYPE SearchType,
469 if (
Child->Type != SearchType) {
473 if ((SearchType != EFI_SECTION_GUID_DEFINED) || (SectionDefinitionGuid ==
NULL)) {
478 if (IS_SECTION2 (GuidedSection)) {
515 if (
CompareGuid (GuidRecorded, GuidedSectionGuid)) {
520 if (!EFI_ERROR (Status) && (Interface !=
NULL)) {
553 VOID *NewStreamBuffer;
554 UINTN NewStreamBufferSize;
555 UINT32 AuthenticationStatus;
558 Context = RpnContext;
560 GuidedHeader = (
EFI_GUID_DEFINED_SECTION *)(Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream);
561 ASSERT (GuidedHeader->
CommonHeader.Type == EFI_SECTION_GUID_DEFINED);
567 Status = GuidedExtraction->ExtractSection (
571 &NewStreamBufferSize,
572 &AuthenticationStatus
580 if ((GuidedHeader->
Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) {
584 AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AUTH_STATUS_ALL;
590 AuthenticationStatus = Context->ParentStream->AuthenticationStatus;
597 AuthenticationStatus,
598 &Context->ChildNode->EncapsulatedStreamHandle
605 gBS->CloseEvent (Event);
606 Context->ChildNode->Event =
NULL;
629 ASSERT (Context !=
NULL);
631 Context->ChildNode = ChildNode;
632 Context->ParentStream = ParentStream;
635 Context->ChildNode->EncapsulationGuid,
639 &Context->Registration
667 IN UINT32 ChildOffset,
677 VOID *NewStreamBuffer;
680 UINTN NewStreamBufferSize;
681 UINT32 AuthenticationStatus;
682 VOID *CompressionSource;
683 UINT32 CompressionSourceSize;
684 UINT32 UncompressedLength;
685 UINT8 CompressionType;
686 UINT16 GuidedSectionAttributes;
698 return EFI_OUT_OF_RESOURCES;
704 Node->Signature = CORE_SECTION_CHILD_SIGNATURE;
705 Node->Type = SectionHeader->Type;
706 if (IS_SECTION2 (SectionHeader)) {
707 Node->Size = SECTION2_SIZE (SectionHeader);
712 Node->OffsetInStream = ChildOffset;
713 Node->EncapsulatedStreamHandle = NULL_STREAM_HANDLE;
714 Node->EncapsulationGuid =
NULL;
719 switch (Node->Type) {
726 return EFI_NOT_FOUND;
731 if (IS_SECTION2 (CompressionHeader)) {
746 if (UncompressedLength > 0) {
747 NewStreamBufferSize = UncompressedLength;
749 if (NewStreamBuffer ==
NULL) {
751 return EFI_OUT_OF_RESOURCES;
758 CopyMem (NewStreamBuffer, CompressionSource, NewStreamBufferSize);
759 }
else if (CompressionType == EFI_STANDARD_COMPRESSION) {
774 CompressionSourceSize,
775 (UINT32 *)&NewStreamBufferSize,
778 if (EFI_ERROR (Status) || (NewStreamBufferSize != UncompressedLength)) {
781 if (!EFI_ERROR (Status)) {
782 Status = EFI_BAD_BUFFER_SIZE;
789 if (ScratchBuffer ==
NULL) {
792 return EFI_OUT_OF_RESOURCES;
798 CompressionSourceSize,
800 (UINT32)NewStreamBufferSize,
805 if (EFI_ERROR (Status)) {
812 NewStreamBuffer =
NULL;
813 NewStreamBufferSize = 0;
820 Stream->AuthenticationStatus,
821 &Node->EncapsulatedStreamHandle
823 if (EFI_ERROR (Status)) {
831 case EFI_SECTION_GUID_DEFINED:
833 if (IS_SECTION2 (GuidedHeader)) {
838 GuidedSectionAttributes = GuidedHeader->
Attributes;
846 Status = GuidedExtraction->ExtractSection (
850 &NewStreamBufferSize,
851 &AuthenticationStatus
853 if (EFI_ERROR (Status)) {
855 return EFI_PROTOCOL_ERROR;
862 if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) {
866 AuthenticationStatus |= Stream->AuthenticationStatus & EFI_AUTH_STATUS_ALL;
872 AuthenticationStatus = Stream->AuthenticationStatus;
879 AuthenticationStatus,
880 &Node->EncapsulatedStreamHandle
882 if (EFI_ERROR (Status)) {
901 AuthenticationStatus = Stream->AuthenticationStatus;
903 if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
904 AuthenticationStatus |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED;
907 if (IS_SECTION2 (GuidedHeader)) {
912 AuthenticationStatus,
913 &Node->EncapsulatedStreamHandle
920 AuthenticationStatus,
921 &Node->EncapsulatedStreamHandle
925 if (EFI_ERROR (Status)) {
985 IN EFI_SECTION_TYPE SearchType,
991 OUT UINT32 *AuthenticationStatus
997 UINT32 NextChildOffset;
1001 ASSERT (*SectionInstance > 0);
1003 if (Depth >=
PcdGet32 (PcdFwVolDxeMaxEncapsulationDepth)) {
1007 CurrentChildNode =
NULL;
1008 ErrorStatus = EFI_NOT_FOUND;
1010 if (SourceStream->StreamLength == 0) {
1011 return EFI_NOT_FOUND;
1025 if (EFI_ERROR (Status)) {
1037 CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (
GetFirstNode (&SourceStream->Children));
1040 ASSERT (CurrentChildNode !=
NULL);
1041 if (
ChildIsType (SourceStream, CurrentChildNode, SearchType, SectionDefinitionGuid)) {
1045 (*SectionInstance)--;
1046 if (*SectionInstance == 0) {
1050 *FoundChild = CurrentChildNode;
1051 *FoundStream = SourceStream;
1052 *AuthenticationStatus = SourceStream->AuthenticationStatus;
1060 ASSERT (*SectionInstance > 0);
1062 if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
1070 SectionDefinitionGuid,
1073 &RecursedFoundStream,
1074 AuthenticationStatus
1076 if (*SectionInstance == 0) {
1082 *FoundChild = RecursedChildNode;
1083 *FoundStream = RecursedFoundStream;
1086 if (Status == EFI_ABORTED) {
1099 ErrorStatus = Status;
1101 }
else if ((CurrentChildNode->Type == EFI_SECTION_GUID_DEFINED) && (SearchType != EFI_SECTION_GUID_DEFINED)) {
1107 ErrorStatus = EFI_PROTOCOL_ERROR;
1110 if (!
IsNodeAtEnd (&SourceStream->Children, &CurrentChildNode->Link)) {
1116 CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (
GetNextNode (&SourceStream->Children, &CurrentChildNode->Link));
1123 NextChildOffset = CurrentChildNode->OffsetInStream + CurrentChildNode->Size;
1127 NextChildOffset += 3;
1128 NextChildOffset &= ~(
UINTN)3;
1133 Status =
CreateChildNode (SourceStream, NextChildOffset, &CurrentChildNode);
1134 if (EFI_ERROR (Status)) {
1138 ASSERT (EFI_ERROR (ErrorStatus));
1166 StreamNode = STREAM_NODE_FROM_LINK (
GetFirstNode (&mStreamRoot));
1168 if (StreamNode->StreamHandle == SearchHandle) {
1169 *FoundStream = StreamNode;
1171 }
else if (
IsNodeAtEnd (&mStreamRoot, &StreamNode->Link)) {
1174 StreamNode = STREAM_NODE_FROM_LINK (
GetNextNode (&mStreamRoot, &StreamNode->Link));
1179 return EFI_NOT_FOUND;
1244 IN EFI_SECTION_TYPE *SectionType,
1249 OUT UINT32 *AuthenticationStatus,
1259 UINT32 ExtractedAuthenticationStatus;
1265 ChildStreamNode =
NULL;
1267 Instance = SectionInstance + 1;
1273 if (EFI_ERROR (Status)) {
1274 Status = EFI_INVALID_PARAMETER;
1275 goto GetSection_Done;
1281 if (SectionType ==
NULL) {
1285 CopySize = StreamNode->StreamLength;
1286 CopyBuffer = StreamNode->StreamBuffer;
1287 *AuthenticationStatus = StreamNode->AuthenticationStatus;
1296 SectionDefinitionGuid,
1300 &ExtractedAuthenticationStatus
1302 if (EFI_ERROR (Status)) {
1303 if (Status == EFI_ABORTED) {
1306 "%a: recursion aborted due to nesting depth\n",
1312 Status = EFI_NOT_FOUND;
1315 goto GetSection_Done;
1320 if (IS_SECTION2 (Section)) {
1321 ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
1323 DEBUG ((DEBUG_ERROR,
"It is a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
1324 Status = EFI_NOT_FOUND;
1325 goto GetSection_Done;
1335 *AuthenticationStatus = ExtractedAuthenticationStatus;
1338 SectionSize = CopySize;
1339 if (*Buffer !=
NULL) {
1343 if (*BufferSize < CopySize) {
1344 Status = EFI_WARN_BUFFER_TOO_SMALL;
1345 CopySize = *BufferSize;
1352 if (*Buffer ==
NULL) {
1353 Status = EFI_OUT_OF_RESOURCES;
1354 goto GetSection_Done;
1358 CopyMem (*Buffer, CopyBuffer, CopySize);
1359 *BufferSize = SectionSize;
1378 ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE);
1384 if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
1392 if (ChildNode->Event !=
NULL) {
1393 gBS->CloseEvent (ChildNode->Event);
1419 IN BOOLEAN FreeStreamBuffer
1434 if (!EFI_ERROR (Status)) {
1441 ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);
1445 if (FreeStreamBuffer) {
1452 Status = EFI_INVALID_PARAMETER;
1547 OUT VOID **OutputBuffer,
1549 OUT UINT32 *AuthenticationStatus
1553 VOID *ScratchBuffer;
1554 VOID *AllocatedOutputBuffer;
1555 UINT32 OutputBufferSize;
1556 UINT32 ScratchBufferSize;
1557 UINT16 SectionAttribute;
1562 ScratchBuffer =
NULL;
1563 AllocatedOutputBuffer =
NULL;
1575 if (EFI_ERROR (Status)) {
1576 DEBUG ((DEBUG_ERROR,
"GetInfo from guided section Failed - %r\n", Status));
1580 if (ScratchBufferSize > 0) {
1585 if (ScratchBuffer ==
NULL) {
1586 return EFI_OUT_OF_RESOURCES;
1590 if (OutputBufferSize > 0) {
1594 AllocatedOutputBuffer =
AllocatePool (OutputBufferSize);
1595 if (AllocatedOutputBuffer ==
NULL) {
1596 if (ScratchBuffer !=
NULL) {
1600 return EFI_OUT_OF_RESOURCES;
1603 *OutputBuffer = AllocatedOutputBuffer;
1609 Status = ExtractGuidedSectionDecode (
1613 AuthenticationStatus
1615 if (EFI_ERROR (Status)) {
1619 if (AllocatedOutputBuffer !=
NULL) {
1623 if (ScratchBuffer !=
NULL) {
1627 DEBUG ((DEBUG_ERROR,
"Extract guided section Failed - %r\n", Status));
1631 if (*OutputBuffer != AllocatedOutputBuffer) {
1636 CopyMem (AllocatedOutputBuffer, *OutputBuffer, OutputBufferSize);
1637 *OutputBuffer = AllocatedOutputBuffer;
1643 *OutputSize = (
UINTN)OutputBufferSize;
1648 if (ScratchBuffer !=
NULL) {
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
BOOLEAN EFIAPI IsNodeAtEnd(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
NODE Child(IN NODE LoopVar6, IN UINT8 LoopVar5)
EFI_STATUS EFIAPI CoreLocateProtocol(IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface)
EFI_TPL EFIAPI CoreRaiseTpl(IN EFI_TPL NewTpl)
EFI_STATUS EFIAPI CoreInstallProtocolInterface(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface)
VOID EFIAPI CoreRestoreTpl(IN EFI_TPL NewTpl)
EFI_STATUS EFIAPI CoreFreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI Decompress(IN CONST EFI_PEI_DECOMPRESS_PPI *This, IN CONST EFI_COMPRESSION_SECTION *CompressionSection, OUT VOID **OutputBuffer, OUT UINTN *OutputSize)
#define ALIGN_POINTER(Pointer, Alignment)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define PcdGet32(TokenName)
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED
#define EFI_SECTION_COMPRESSION
#define EFI_NOT_COMPRESSED
#define SECTION_SIZE(SectionHeaderPtr)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
UINT32 UncompressedLength
EFI_COMMON_SECTION_HEADER CommonHeader
EFI_GUID SectionDefinitionGuid