/** @file
  Section Extraction Protocol implementation.
  
  Stream database is implemented as a linked list of section streams,
  where each stream contains a linked list of children, which may be leaves or
  encapsulations.  
  
  Children that are encapsulations generate new stream entries
  when they are created.  Streams can also be created by calls to 
  SEP->OpenSectionStream().
  
  The database is only created far enough to return the requested data from
  any given stream, or to determine that the requested data is not found.
  
  If a GUIDed encapsulation is encountered, there are three possiblilites.
  
  1) A support protocol is found, in which the stream is simply processed with
     the support protocol.
     
  2) A support protocol is not found, but the data is available to be read
     without processing.  In this case, the database is built up through the
     recursions to return the data, and a RPN event is set that will enable
     the stream in question to be refreshed if and when the required section
     extraction protocol is published.This insures the AuthenticationStatus 
     does not become stale in the cache.
     
  3) A support protocol is not found, and the data is not available to be read
     without it.  This results in EFI_PROTOCOL_ERROR.

Copyright (c) 2006 - 2010, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <FrameworkDxe.h>

#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Protocol/Decompress.h>
#include <Protocol/GuidedSectionExtraction.h>
#include <Protocol/SectionExtraction.h>

//
// Local defines and typedefs
//
#define FRAMEWORK_SECTION_CHILD_SIGNATURE  SIGNATURE_32('S','X','F','S')
#define CHILD_SECTION_NODE_FROM_LINK(Node) \
  CR (Node, FRAMEWORK_SECTION_CHILD_NODE, Link, FRAMEWORK_SECTION_CHILD_SIGNATURE)

typedef struct {
  UINT32                      Signature;
  LIST_ENTRY                  Link;
  UINT32                      Type;
  UINT32                      Size;
  //
  // StreamBase + OffsetInStream == pointer to section header in stream.  The
  // stream base is always known when walking the sections within.
  //
  UINT32                      OffsetInStream;
  //
  // Then EncapsulatedStreamHandle below is always 0 if the section is NOT an
  // encapsulating section.  Otherwise, it contains the stream handle
  // of the encapsulated stream.  This handle is ALWAYS produced any time an
  // encapsulating child is encountered, irrespective of whether the
  // encapsulated stream is processed further.
  //
  UINTN                       EncapsulatedStreamHandle;
  EFI_GUID                    *EncapsulationGuid;
} FRAMEWORK_SECTION_CHILD_NODE;

#define FRAMEWORK_SECTION_STREAM_SIGNATURE SIGNATURE_32('S','X','S','S')
#define STREAM_NODE_FROM_LINK(Node) \
  CR (Node, FRAMEWORK_SECTION_STREAM_NODE, Link, FRAMEWORK_SECTION_STREAM_SIGNATURE)

typedef struct {
  UINT32                      Signature;
  LIST_ENTRY                  Link;
  UINTN                       StreamHandle;
  UINT8                       *StreamBuffer;
  UINTN                       StreamLength;
  LIST_ENTRY                  Children;
  //
  // Authentication status is from GUIDed encapsulations.
  //
  UINT32                      AuthenticationStatus;
} FRAMEWORK_SECTION_STREAM_NODE;

#define NULL_STREAM_HANDLE    0

typedef struct {
  FRAMEWORK_SECTION_CHILD_NODE     *ChildNode;
  FRAMEWORK_SECTION_STREAM_NODE    *ParentStream;
  VOID                             *Registration;
  EFI_EVENT                        Event;
} RPN_EVENT_CONTEXT;

/**
  SEP member function.  This function creates and returns a new section stream
  handle to represent the new section stream.

  @param This                 Indicates the calling context.
  @param SectionStreamLength  Size in bytes of the section stream.
  @param SectionStream        Buffer containing the new section stream.
  @param SectionStreamHandle  A pointer to a caller allocated UINTN that on output
                              contains the new section stream handle.

  @retval EFI_SUCCESS           Section wase opened successfully.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
  @retval EFI_INVALID_PARAMETER Section stream does not end concident with end of
                                last section.

**/
EFI_STATUS
EFIAPI
OpenSectionStream (
  IN     EFI_SECTION_EXTRACTION_PROTOCOL           *This,
  IN     UINTN                                     SectionStreamLength,
  IN     VOID                                      *SectionStream,
     OUT UINTN                                     *SectionStreamHandle
  )
;

/**
  SEP member function.  Retrieves requested section from section stream.

  @param This                  Pointer to SEP instance.
  @param SectionStreamHandle   The section stream from which to extract the requested
                               section.
  @param SectionType           A pointer to the type of section to search for.
  @param SectionDefinitionGuid If the section type is EFI_SECTION_GUID_DEFINED, then
                               SectionDefinitionGuid indicates which of these types
                               of sections to search for.
  @param SectionInstance       Indicates which instance of the requested section to
                               return.
  @param Buffer                Double indirection to buffer.  If *Buffer is non-null on
                               input, then the buffer is caller allocated.  If
                               *Buffer is NULL, then the buffer is callee allocated.
                               In either case, the requried buffer size is returned
                               in *BufferSize.
  @param BufferSize            On input, indicates the size of *Buffer if *Buffer is
                               non-null on input.  On output, indicates the required
                               size (allocated size if callee allocated) of *Buffer.
  @param AuthenticationStatus  Indicates the authentication status of the retrieved
                               section.

 
  @retval EFI_SUCCESS           Section was retrieved successfully
  @retval EFI_PROTOCOL_ERROR    A GUID defined section was encountered in the section 
                                stream with its EFI_GUIDED_SECTION_PROCESSING_REQUIRED
                                bit set, but there was no corresponding GUIDed Section 
                                Extraction Protocol in the handle database.  *Buffer is 
                                unmodified.
  @retval EFI_NOT_FOUND         An error was encountered when parsing the SectionStream.
                                This indicates the SectionStream  is not correctly 
                                formatted.
  @retval EFI_NOT_FOUND         The requested section does not exist.
  @retval EFI_OUT_OF_RESOURCES  The system has insufficient resources to process the 
                                request.
  @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist.
  @retval EFI_WARN_TOO_SMALL    The size of the caller allocated input buffer is 
                                insufficient to contain the requested section.  The 
                                input buffer is filled and contents are section contents
                                are truncated.

**/
EFI_STATUS
EFIAPI
GetSection (
  IN EFI_SECTION_EXTRACTION_PROTOCOL                    *This,
  IN UINTN                                              SectionStreamHandle,
  IN EFI_SECTION_TYPE                                   *SectionType,
  IN EFI_GUID                                           *SectionDefinitionGuid,
  IN UINTN                                              SectionInstance,
  IN VOID                                               **Buffer,
  IN OUT UINTN                                          *BufferSize,
  OUT UINT32                                            *AuthenticationStatus
  )
;

/**
  SEP member function.  Deletes an existing section stream

  @param This                   Indicates the calling context.
  @param StreamHandleToClose    Indicates the stream to close

  @retval EFI_SUCCESS           Section stream was closed successfully.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
  @retval EFI_INVALID_PARAMETER Section stream does not end concident with end of
                                last section.

**/
EFI_STATUS
EFIAPI
CloseSectionStream (
  IN  EFI_SECTION_EXTRACTION_PROTOCOL           *This,
  IN  UINTN                                     StreamHandleToClose
  )
;

//
// Module globals
//
LIST_ENTRY mStreamRoot = INITIALIZE_LIST_HEAD_VARIABLE (mStreamRoot);

EFI_HANDLE mSectionExtractionHandle = NULL;

EFI_SECTION_EXTRACTION_PROTOCOL mSectionExtraction = { 
  OpenSectionStream, 
  GetSection, 
  CloseSectionStream
};

/**
  Entry point of the section extraction code. Initializes an instance of the 
  section extraction interface and installs it on a new handle.

  @param ImageHandle             A handle for the image that is initializing this driver
  @param SystemTable             A pointer to the EFI system table        

  @retval EFI_SUCCESS            Driver initialized successfully
  @retval EFI_OUT_OF_RESOURCES   Could not allocate needed resources

**/
EFI_STATUS
EFIAPI
SectionExtractionEntryPoint (
  IN EFI_HANDLE                   ImageHandle,
  IN EFI_SYSTEM_TABLE             *SystemTable
  )
{
  EFI_STATUS                         Status;

  //
  // Install SEP to a new handle
  //
  Status = gBS->InstallProtocolInterface (
                  &mSectionExtractionHandle,
                  &gEfiSectionExtractionProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mSectionExtraction
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**

  Check if a stream is valid.

  @param SectionStream         The section stream to be checked
  @param SectionStreamLength   The length of section stream

  @return A boolean value indicating the validness of the section stream.

**/
BOOLEAN
IsValidSectionStream (
  IN  VOID              *SectionStream,
  IN  UINTN             SectionStreamLength
  )
{
  UINTN                       TotalLength;
  UINTN                       SectionLength;
  EFI_COMMON_SECTION_HEADER   *SectionHeader;
  EFI_COMMON_SECTION_HEADER   *NextSectionHeader;

  TotalLength = 0;
  SectionHeader = (EFI_COMMON_SECTION_HEADER *)SectionStream;
  
  while (TotalLength < SectionStreamLength) {
    SectionLength = SECTION_SIZE (SectionHeader);
    TotalLength += SectionLength;

    if (TotalLength == SectionStreamLength) {
      return TRUE;    
    }

    //
    // Move to the next byte following the section...
    //
    SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength);
    
    //
    // Figure out where the next section begins
    //
    NextSectionHeader = ALIGN_POINTER(SectionHeader, 4);
    TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader;
    SectionHeader = NextSectionHeader;
  }

  ASSERT (FALSE);
  return FALSE;
}

/**
  Worker function.  Constructor for section streams.

  @param SectionStreamLength   Size in bytes of the section stream.
  @param SectionStream         Buffer containing the new section stream.
  @param AllocateBuffer        Indicates whether the stream buffer is to be copied
                               or the input buffer is to be used in place.
  @param AuthenticationStatus  Indicates the default authentication status for the
                               new stream.
  @param SectionStreamHandle   A pointer to a caller allocated section stream handle.

  @retval EFI_SUCCESS           Stream was added to stream database.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.

**/
EFI_STATUS
OpenSectionStreamEx (
  IN     UINTN                                     SectionStreamLength,
  IN     VOID                                      *SectionStream,
  IN     BOOLEAN                                   AllocateBuffer,
  IN     UINT32                                    AuthenticationStatus,   
     OUT UINTN                                     *SectionStreamHandle
  )
{
  FRAMEWORK_SECTION_STREAM_NODE    *NewStream;
  EFI_TPL                     OldTpl;
  
  //
  // Allocate a new stream
  //
  NewStream = AllocatePool (sizeof (FRAMEWORK_SECTION_STREAM_NODE));
  if (NewStream == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  if (AllocateBuffer) { 
    //
    // if we're here, we're double buffering, allocate the buffer and copy the
    // data in
    //
    if (SectionStreamLength > 0) {
      NewStream->StreamBuffer = AllocatePool (SectionStreamLength); 
      if (NewStream->StreamBuffer == NULL) {
        FreePool (NewStream);
        return EFI_OUT_OF_RESOURCES;
      }
      //
      // Copy in stream data
      //
      CopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength);
    } else {
      //
      // It's possible to have a zero length section stream.
      //
      NewStream->StreamBuffer = NULL;
    }
  } else {
    //
    // If were here, the caller has supplied the buffer (it's an internal call)
    // so just assign the buffer.  This happens when we open section streams
    // as a result of expanding an encapsulating section.
    //
    NewStream->StreamBuffer = SectionStream;
  }
  
  //
  // Initialize the rest of the section stream
  //
  NewStream->Signature = FRAMEWORK_SECTION_STREAM_SIGNATURE;
  NewStream->StreamHandle = (UINTN) NewStream;
  NewStream->StreamLength = SectionStreamLength;
  InitializeListHead (&NewStream->Children);
  NewStream->AuthenticationStatus = AuthenticationStatus;
  
  //
  // Add new stream to stream list
  //
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  InsertTailList (&mStreamRoot, &NewStream->Link);
  gBS->RestoreTPL (OldTpl);

  *SectionStreamHandle = NewStream->StreamHandle;
  
  return EFI_SUCCESS;
}

/**
  SEP member function.  This function creates and returns a new section stream
  handle to represent the new section stream.

  @param This                 Indicates the calling context.
  @param SectionStreamLength  Size in bytes of the section stream.
  @param SectionStream        Buffer containing the new section stream.
  @param SectionStreamHandle  A pointer to a caller allocated UINTN that on output
                              contains the new section stream handle.

  @retval EFI_SUCCESS           Section wase opened successfully.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
  @retval EFI_INVALID_PARAMETER Section stream does not end concident with end of
                                last section.

**/
EFI_STATUS
EFIAPI
OpenSectionStream (
  IN     EFI_SECTION_EXTRACTION_PROTOCOL           *This,
  IN     UINTN                                     SectionStreamLength,
  IN     VOID                                      *SectionStream,
     OUT UINTN                                     *SectionStreamHandle
  )
{
  //
  // Check to see section stream looks good...
  //
  if (!IsValidSectionStream (SectionStream, SectionStreamLength)) {
    return EFI_INVALID_PARAMETER;
  }
  
  return OpenSectionStreamEx ( 
          SectionStreamLength, 
          SectionStream,
          TRUE,
          0,
          SectionStreamHandle
          );
}

/**
  Worker function.  Determine if the input stream:child matches the input type.

  @param Stream                 Indicates the section stream associated with the child
  @param Child                  Indicates the child to check
  @param SearchType             Indicates the type of section to check against for
  @param SectionDefinitionGuid  Indicates the GUID to check against if the type is
                                EFI_SECTION_GUID_DEFINED

  @retval TRUE                  The child matches
  @retval FALSE                 The child doesn't match

**/
BOOLEAN
ChildIsType (
  IN FRAMEWORK_SECTION_STREAM_NODE *Stream,
  IN FRAMEWORK_SECTION_CHILD_NODE  *Child,
  IN EFI_SECTION_TYPE         SearchType,
  IN EFI_GUID                 *SectionDefinitionGuid
  )
{
  EFI_GUID_DEFINED_SECTION    *GuidedSection;
  
  if (SearchType == EFI_SECTION_ALL) {
    return TRUE;
  }
  if (Child->Type != SearchType) {
    return FALSE;
  }
  if (SearchType != EFI_SECTION_GUID_DEFINED) {
    return TRUE;
  }
  GuidedSection = (EFI_GUID_DEFINED_SECTION * )(Stream->StreamBuffer + Child->OffsetInStream);
  return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid);
}

/**
  Create a protocol notification event and return it.

  @param ProtocolGuid    Protocol to register notification event on.
  @param NotifyTpl       Maximum TPL to signal the NotifyFunction.
  @param NotifyFunction  EFI notification routine.
  @param NotifyContext   Context passed into Event when it is created.
  @param Registration    Registration key returned from RegisterProtocolNotify().
  @param SignalFlag      Boolean value to decide whether kick the event after register or not.

  @return The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
           is added to the system.

**/
EFI_EVENT
CreateProtocolNotifyEvent (
  IN EFI_GUID             *ProtocolGuid,
  IN EFI_TPL              NotifyTpl,
  IN EFI_EVENT_NOTIFY     NotifyFunction,
  IN VOID                 *NotifyContext,
  OUT VOID                **Registration,
  IN  BOOLEAN             SignalFlag
  )
{
  EFI_STATUS              Status;
  EFI_EVENT               Event;

  //
  // Create the event
  //

  Status = gBS->CreateEvent (
            EVT_NOTIFY_SIGNAL,
            NotifyTpl,
            NotifyFunction,
            NotifyContext,
           &Event
            );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for protocol notifactions on this event
  //

  Status = gBS->RegisterProtocolNotify (
            ProtocolGuid,
            Event,
            Registration
            );
  ASSERT_EFI_ERROR (Status);

  if (SignalFlag) {
    //
    // Kick the event so we will perform an initial pass of
    // current installed drivers
    //
    gBS->SignalEvent (Event);
  }

  return Event;
}

/**
  RPN callback function.  Removes a stale section stream and re-initializes it
  with an updated AuthenticationStatus.

  @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;
  
  Status = CloseSectionStream (&mSectionExtraction, Context->ChildNode->EncapsulatedStreamHandle);
  if (!EFI_ERROR (Status)) {
    //
    // The stream closed successfully, so re-open the stream with correct AuthenticationStatus
    //
  
    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);
    ASSERT_EFI_ERROR (Status);

    
    Status = GuidedExtraction->ExtractSection (
                                 GuidedExtraction,
                                 GuidedHeader,
                                 &NewStreamBuffer,
                                 &NewStreamBufferSize,
                                 &AuthenticationStatus
                                 );
    ASSERT_EFI_ERROR (Status);
    //
    // OR in the parent stream's aggregagate status.
    //
    AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;
    Status = OpenSectionStreamEx (
               NewStreamBufferSize,
               NewStreamBuffer,
               FALSE,
               AuthenticationStatus,
               &Context->ChildNode->EncapsulatedStreamHandle
               );
    ASSERT_EFI_ERROR (Status);
  }

  //
  //  If above, the stream  did not close successfully, it indicates it's
  //  alread been closed by someone, so just destroy the event and be done with
  //  it.
  //
  
  gBS->CloseEvent (Event);
  FreePool (Context);
}  

/**
  Worker function.  Constructor for RPN event if needed to keep AuthenticationStatus
  cache correct 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 FRAMEWORK_SECTION_STREAM_NODE       *ParentStream,
  IN FRAMEWORK_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 = CreateProtocolNotifyEvent (
                    Context->ChildNode->EncapsulationGuid,
                    TPL_NOTIFY,
                    NotifyGuidedExtraction,
                    Context,
                    &Context->Registration,
                    FALSE
                    );
}

/**
  Worker function.  Constructor for new child nodes.

  @param Stream                Indicates the section stream in which to add the child.
  @param ChildOffset           Indicates the offset in Stream that is the beginning
                               of the child section.
  @param ChildNode             Indicates the Callee allocated and initialized child.

  @retval EFI_SUCCESS          Child node was found and returned.
  @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
  @retval EFI_PROTOCOL_ERROR   Encapsulation sections produce new stream handles when
                               the child node is created.  If the section type is GUID
                               defined, and the extraction GUID does not exist, and
                               producing the stream requires the GUID, then a protocol
                               error is generated and no child is produced.
                               Values returned by OpenSectionStreamEx.

**/
EFI_STATUS
CreateChildNode (
  IN     FRAMEWORK_SECTION_STREAM_NODE              *Stream,
  IN     UINT32                                ChildOffset,
     OUT FRAMEWORK_SECTION_CHILD_NODE               **ChildNode
  )
{
  EFI_STATUS                                   Status;
  EFI_COMMON_SECTION_HEADER                    *SectionHeader;
  EFI_COMPRESSION_SECTION                      *CompressionHeader;
  EFI_GUID_DEFINED_SECTION                     *GuidedHeader;
  EFI_DECOMPRESS_PROTOCOL                      *Decompress;
  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL       *GuidedExtraction;
  VOID                                         *NewStreamBuffer;
  VOID                                         *ScratchBuffer;
  UINT32                                       ScratchSize;
  UINTN                                        NewStreamBufferSize;
  UINT32                                       AuthenticationStatus;
  UINT32                                       SectionLength;
    
  FRAMEWORK_SECTION_CHILD_NODE                      *Node;

  SectionHeader = (EFI_COMMON_SECTION_HEADER *) (Stream->StreamBuffer + ChildOffset);

  //
  // Allocate a new node
  //
  *ChildNode = AllocatePool (sizeof (FRAMEWORK_SECTION_CHILD_NODE));
  Node = *ChildNode;
  if (Node == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  //
  // Now initialize it
  //
  Node->Signature = FRAMEWORK_SECTION_CHILD_SIGNATURE;
  Node->Type = SectionHeader->Type;
  Node->Size = SECTION_SIZE (SectionHeader);
  Node->OffsetInStream = ChildOffset;
  Node->EncapsulatedStreamHandle = NULL_STREAM_HANDLE;
  Node->EncapsulationGuid = NULL;
  
  //
  // If it's an encapsulating section, then create the new section stream also
  //
  switch (Node->Type) {
    case EFI_SECTION_COMPRESSION:
      //
      // Get the CompressionSectionHeader
      //
      ASSERT (Node->Size >= sizeof (EFI_COMPRESSION_SECTION));
      
      CompressionHeader = (EFI_COMPRESSION_SECTION *) SectionHeader;
      
      //
      // Allocate space for the new stream
      //
      if (CompressionHeader->UncompressedLength > 0) {
        NewStreamBufferSize = CompressionHeader->UncompressedLength;
        NewStreamBuffer = AllocatePool (NewStreamBufferSize);
        if (NewStreamBuffer == NULL) {
          FreePool (Node);
          return EFI_OUT_OF_RESOURCES;
        }
        
        if (CompressionHeader->CompressionType == EFI_NOT_COMPRESSED) {
          //
          // stream is not actually compressed, just encapsulated.  So just copy it.
          //
          CopyMem (NewStreamBuffer, CompressionHeader + 1, NewStreamBufferSize);
        } else if (CompressionHeader->CompressionType == EFI_STANDARD_COMPRESSION) {
          //
          // Only support the EFI_SATNDARD_COMPRESSION algorithm.
          // 

          //
          // Decompress the stream
          //
          Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **)&Decompress);
          
          ASSERT_EFI_ERROR (Status);
          
          Status = Decompress->GetInfo (
                                 Decompress,
                                 CompressionHeader + 1,
                                 Node->Size - sizeof (EFI_COMPRESSION_SECTION),
                                 (UINT32 *)&NewStreamBufferSize,
                                 &ScratchSize
                                 );
          ASSERT_EFI_ERROR (Status);
          ASSERT (NewStreamBufferSize == CompressionHeader->UncompressedLength);

          ScratchBuffer = AllocatePool (ScratchSize);
          if (ScratchBuffer == NULL) {
            FreePool (Node);
            FreePool (NewStreamBuffer);
            return EFI_OUT_OF_RESOURCES;
          }

          Status = Decompress->Decompress (
                                 Decompress,
                                 CompressionHeader + 1,
                                 Node->Size - sizeof (EFI_COMPRESSION_SECTION),
                                 NewStreamBuffer,
                                 (UINT32)NewStreamBufferSize,
                                 ScratchBuffer,
                                 ScratchSize
                                 );
          ASSERT_EFI_ERROR (Status);
          FreePool (ScratchBuffer);                                           
        }
      } else {
        NewStreamBuffer = NULL;
        NewStreamBufferSize = 0;
      }
      
      Status = OpenSectionStreamEx (
                 NewStreamBufferSize,
                 NewStreamBuffer,
                 FALSE,
                 Stream->AuthenticationStatus,
                 &Node->EncapsulatedStreamHandle
                 );
      if (EFI_ERROR (Status)) {
        FreePool (Node);
        FreePool (NewStreamBuffer);
        return Status;
      }
      break;

    case EFI_SECTION_GUID_DEFINED:
      GuidedHeader = (EFI_GUID_DEFINED_SECTION *) SectionHeader;
      Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid;
      Status = gBS->LocateProtocol (Node->EncapsulationGuid, NULL, (VOID **)&GuidedExtraction);
      if (!EFI_ERROR (Status)) {
        //
        // NewStreamBuffer is always allocated by ExtractSection... No caller
        // allocation here.
        //
        Status = GuidedExtraction->ExtractSection (
                                     GuidedExtraction,
                                     GuidedHeader,
                                     &NewStreamBuffer,
                                     &NewStreamBufferSize,
                                     &AuthenticationStatus
                                     );
        if (EFI_ERROR (Status)) {
          FreePool (*ChildNode);
          return EFI_PROTOCOL_ERROR;
        }
        
        //
        // 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) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
          //
          // OR in the parent stream's aggregate status.
          //
          AuthenticationStatus |= Stream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;
        } else {
          //
          // since there's no authentication data contributed by the section,
          // just inherit the full value from our immediate parent.
          //
          AuthenticationStatus = Stream->AuthenticationStatus;
        }
        
        Status = OpenSectionStreamEx (
                   NewStreamBufferSize,
                   NewStreamBuffer,
                   FALSE,
                   AuthenticationStatus,
                   &Node->EncapsulatedStreamHandle
                   );
        if (EFI_ERROR (Status)) {
          FreePool (*ChildNode);
          FreePool (NewStreamBuffer);
          return Status;
        }
      } else {
        //
        // There's no GUIDed section extraction protocol available.
        //
        if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == EFI_GUIDED_SECTION_PROCESSING_REQUIRED) {
          //
          // If the section REQUIRES an extraction protocol, then we're toast
          //
          FreePool (*ChildNode);
          return EFI_PROTOCOL_ERROR;
        }
        
        //
        // Figure out the proper authentication status
        //
        AuthenticationStatus = Stream->AuthenticationStatus;
        if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
          //
          //  The local status of the new stream is contained in 
          //  AuthenticaionStatus.  This value needs to be ORed into the
          //  Aggregate bits also...
          //
          
          //
          // Clear out and initialize the local status
          //
          AuthenticationStatus &= ~EFI_LOCAL_AUTH_STATUS_ALL;
          AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED;
          //
          // OR local status into aggregate status
          //
          AuthenticationStatus |= AuthenticationStatus >> 16;
        }
        
        SectionLength = SECTION_SIZE (GuidedHeader);
        Status = OpenSectionStreamEx (
                   SectionLength - GuidedHeader->DataOffset,
                   (UINT8 *) GuidedHeader + GuidedHeader->DataOffset,
                   TRUE,
                   AuthenticationStatus,
                   &Node->EncapsulatedStreamHandle
                   );
        if (EFI_ERROR (Status)) {
          FreePool (Node);
          return Status;
        }
      }
      
      if ((AuthenticationStatus & EFI_LOCAL_AUTH_STATUS_ALL) == 
            (EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED)) {
        //
        // Need to register for RPN for when the required GUIDed extraction
        // protocol becomes available.  This will enable us to refresh the
        // AuthenticationStatus cached in the Stream if it's ever requested
        // again.
        //
        CreateGuidedExtractionRpnEvent (Stream, Node);
      }
      
      break;

    default:
      
      //
      // Nothing to do if it's a leaf
      //
      break;
  }
  
  //
  // Last, add the new child node to the stream
  //
  InsertTailList (&Stream->Children, &Node->Link);

  return EFI_SUCCESS;
}

/**
  Worker function  Recursively searches / builds section stream database
  looking for requested section.


  @param SourceStream          Indicates the section stream in which to do the search.
  @param SearchType            Indicates the type of section to search for.
  @param SectionInstance       Indicates which instance of section to find.  This is
                               an in/out parameter to deal with recursions.
  @param SectionDefinitionGuid Guid of section definition
  @param FoundChild            Output indicating the child node that is found.
  @param FoundStream           Output indicating which section stream the child was
                               found in.  If this stream was generated as a result of
                               an encapsulation section, the streamhandle is visible
                               within the SEP driver only.
  @param AuthenticationStatus  Indicates the authentication status of the found section.

  @retval EFI_SUCCESS          Child node was found and returned.
  @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
  @retval EFI_NOT_FOUND        Requested child node does not exist.
  @retval EFI_PROTOCOL_ERROR   A required GUIDED section extraction protocol does not
                               exist

**/
EFI_STATUS
FindChildNode (
  IN     FRAMEWORK_SECTION_STREAM_NODE                   *SourceStream,
  IN     EFI_SECTION_TYPE                           SearchType,
  IN OUT UINTN                                      *SectionInstance,
  IN     EFI_GUID                                   *SectionDefinitionGuid,
  OUT    FRAMEWORK_SECTION_CHILD_NODE                    **FoundChild,
  OUT    FRAMEWORK_SECTION_STREAM_NODE                   **FoundStream,
  OUT    UINT32                                     *AuthenticationStatus
  )
{
  FRAMEWORK_SECTION_CHILD_NODE                       *CurrentChildNode;
  FRAMEWORK_SECTION_CHILD_NODE                       *RecursedChildNode;
  FRAMEWORK_SECTION_STREAM_NODE                      *RecursedFoundStream;
  UINT32                                        NextChildOffset;
  EFI_STATUS                                    ErrorStatus;
  EFI_STATUS                                    Status;
  
  CurrentChildNode = NULL;
  ErrorStatus = EFI_NOT_FOUND;
  
  if (SourceStream->StreamLength == 0) {
    return EFI_NOT_FOUND;
  }
  
  if (IsListEmpty (&SourceStream->Children) && 
                   SourceStream->StreamLength >= sizeof (EFI_COMMON_SECTION_HEADER)) {
    //
    // This occurs when a section stream exists, but no child sections
    // have been parsed out yet.  Therefore, extract the first child and add it
    // to the list of children so we can get started.
    // Section stream may contain an array of zero or more bytes.
    // So, its size should be >= the size of commen section header.
    //
    Status = CreateChildNode (SourceStream, 0, &CurrentChildNode);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  
  //
  // At least one child has been parsed out of the section stream.  So, walk
  // through the sections that have already been parsed out looking for the
  // requested section, if necessary, continue parsing section stream and
  // adding children until either the requested section is found, or we run
  // out of data
  //
  CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetFirstNode(&SourceStream->Children));

  for (;;) {
    if (ChildIsType (SourceStream, CurrentChildNode, SearchType, SectionDefinitionGuid)) {
      //
      // The type matches, so check the instance count to see if it's the one we want
      //
      (*SectionInstance)--;
      if (*SectionInstance == 0) {
        //
        // Got it!
        //
        *FoundChild = CurrentChildNode;
        *FoundStream = SourceStream;
        *AuthenticationStatus = SourceStream->AuthenticationStatus;
        return EFI_SUCCESS;
      }
    }
    
    ASSERT (CurrentChildNode != NULL);
    if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
      //
      // If the current node is an encapsulating node, recurse into it...
      //
      Status = FindChildNode (
                (FRAMEWORK_SECTION_STREAM_NODE *)CurrentChildNode->EncapsulatedStreamHandle,
                SearchType,
                SectionInstance,
                SectionDefinitionGuid,
                &RecursedChildNode,
                &RecursedFoundStream,
                AuthenticationStatus
                );
      //
      // If the status is not EFI_SUCCESS, just save the error code and continue
      // to find the request child node in the rest stream.
      //
      if (*SectionInstance == 0) {
        ASSERT_EFI_ERROR (Status);
        *FoundChild = RecursedChildNode;
        *FoundStream = RecursedFoundStream;
        return EFI_SUCCESS;
      } else {
        ErrorStatus = Status;
      }
    }
    
    if (!IsNodeAtEnd (&SourceStream->Children, &CurrentChildNode->Link)) {
      //
      // We haven't found the child node we're interested in yet, but there's
      // still more nodes that have already been parsed so get the next one
      // and continue searching..
      //
      CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetNextNode (&SourceStream->Children, &CurrentChildNode->Link));
    } else {
      //
      // We've exhausted children that have already been parsed, so see if
      // there's any more data and continue parsing out more children if there
      // is.
      //
      NextChildOffset = CurrentChildNode->OffsetInStream + CurrentChildNode->Size;
      //
      // Round up to 4 byte boundary
      //
      NextChildOffset += 3;
      NextChildOffset &= ~(UINTN)3;
      if (NextChildOffset <= SourceStream->StreamLength - sizeof (EFI_COMMON_SECTION_HEADER)) {
        //
        // There's an unparsed child remaining in the stream, so create a new child node
        //
        Status = CreateChildNode (SourceStream, NextChildOffset, &CurrentChildNode);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      } else {
        ASSERT (EFI_ERROR (ErrorStatus));
        return ErrorStatus;
      }
    }
  }
}

/**
  Worker function.  Search stream database for requested stream handle.

  @param SearchHandle        Indicates which stream to look for.
  @param FoundStream         Output pointer to the found stream.

  @retval EFI_SUCCESS        StreamHandle was found and *FoundStream contains
                             the stream node.
  @retval EFI_NOT_FOUND      SearchHandle was not found in the stream database.

**/
EFI_STATUS
FindStreamNode (
  IN  UINTN                                     SearchHandle,
  OUT FRAMEWORK_SECTION_STREAM_NODE                  **FoundStream
  )
{  
  FRAMEWORK_SECTION_STREAM_NODE                      *StreamNode;
  
  if (!IsListEmpty (&mStreamRoot)) {
    StreamNode = STREAM_NODE_FROM_LINK (GetFirstNode (&mStreamRoot));
    for (;;) {
      if (StreamNode->StreamHandle == SearchHandle) {
        *FoundStream = StreamNode;
        return EFI_SUCCESS;
      } else if (IsNodeAtEnd (&mStreamRoot, &StreamNode->Link)) {
        break;
      } else {
        StreamNode = STREAM_NODE_FROM_LINK (GetNextNode (&mStreamRoot, &StreamNode->Link));
      }
    }
  }
  
  return EFI_NOT_FOUND;
}
  
/**
  SEP member function.  Retrieves requested section from section stream.

  @param This                  Pointer to SEP instance.
  @param SectionStreamHandle   The section stream from which to extract the requested
                               section.
  @param SectionType           A pointer to the type of section to search for.
  @param SectionDefinitionGuid If the section type is EFI_SECTION_GUID_DEFINED, then
                               SectionDefinitionGuid indicates which of these types
                               of sections to search for.
  @param SectionInstance       Indicates which instance of the requested section to
                               return.
  @param Buffer                Double indirection to buffer.  If *Buffer is non-null on
                               input, then the buffer is caller allocated.  If
                               *Buffer is NULL, then the buffer is callee allocated.
                               In either case, the requried buffer size is returned
                               in *BufferSize.
  @param BufferSize            On input, indicates the size of *Buffer if *Buffer is
                               non-null on input.  On output, indicates the required
                               size (allocated size if callee allocated) of *Buffer.
  @param AuthenticationStatus  Indicates the authentication status of the retrieved
                               section.

 
  @retval EFI_SUCCESS           Section was retrieved successfully
  @retval EFI_PROTOCOL_ERROR    A GUID defined section was encountered in the section 
                                stream with its EFI_GUIDED_SECTION_PROCESSING_REQUIRED
                                bit set, but there was no corresponding GUIDed Section 
                                Extraction Protocol in the handle database.  *Buffer is 
                                unmodified.
  @retval EFI_NOT_FOUND         An error was encountered when parsing the SectionStream.
                                This indicates the SectionStream  is not correctly 
                                formatted.
  @retval EFI_NOT_FOUND         The requested section does not exist.
  @retval EFI_OUT_OF_RESOURCES  The system has insufficient resources to process the 
                                request.
  @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist.
  @retval EFI_WARN_TOO_SMALL    The size of the caller allocated input buffer is 
                                insufficient to contain the requested section.  The 
                                input buffer is filled and contents are section contents
                                are truncated.

**/
EFI_STATUS
EFIAPI
GetSection (
  IN EFI_SECTION_EXTRACTION_PROTOCOL                    *This,
  IN UINTN                                              SectionStreamHandle,
  IN EFI_SECTION_TYPE                                   *SectionType,
  IN EFI_GUID                                           *SectionDefinitionGuid,
  IN UINTN                                              SectionInstance,
  IN VOID                                               **Buffer,
  IN OUT UINTN                                          *BufferSize,
  OUT UINT32                                            *AuthenticationStatus
  )
{
  FRAMEWORK_SECTION_STREAM_NODE                              *StreamNode;
  EFI_TPL                                               OldTpl;
  EFI_STATUS                                            Status;
  FRAMEWORK_SECTION_CHILD_NODE                               *ChildNode;
  FRAMEWORK_SECTION_STREAM_NODE                              *ChildStreamNode;
  UINTN                                                 CopySize;
  UINT32                                                ExtractedAuthenticationStatus;
  UINTN                                                 Instance;
  UINT8                                                 *CopyBuffer;
  UINTN                                                 SectionSize;
  

  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  Instance = SectionInstance + 1;
  
  //
  // Locate target stream
  //
  Status = FindStreamNode (SectionStreamHandle, &StreamNode);
  if (EFI_ERROR (Status)) {
    Status = EFI_INVALID_PARAMETER;
    goto GetSection_Done;
  }
  
  //
  // Found the stream, now locate and return the appropriate section
  //
  if (SectionType == NULL) {
    //
    // SectionType == NULL means return the WHOLE section stream...
    //
    CopySize = StreamNode->StreamLength;
    CopyBuffer = StreamNode->StreamBuffer;
    *AuthenticationStatus = StreamNode->AuthenticationStatus;
  } else {
    //
    // There's a requested section type, so go find it and return it...
    //
    Status = FindChildNode (
                      StreamNode, 
                      *SectionType, 
                      &Instance, 
                      SectionDefinitionGuid,
                      &ChildNode,
                      &ChildStreamNode, 
                      &ExtractedAuthenticationStatus
                      );
    if (EFI_ERROR (Status)) {
      goto GetSection_Done;
    }
    ASSERT (ChildNode != NULL);
    ASSERT (ChildStreamNode != NULL);
    CopySize = ChildNode->Size - sizeof (EFI_COMMON_SECTION_HEADER);
    CopyBuffer = ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream + sizeof (EFI_COMMON_SECTION_HEADER);
    *AuthenticationStatus = ExtractedAuthenticationStatus;
  }   
    
  SectionSize = CopySize;  
  if (*Buffer != NULL) {
    //
    // Caller allocated buffer.  Fill to size and return required size...
    //
    if (*BufferSize < CopySize) {
      Status = EFI_WARN_BUFFER_TOO_SMALL;
      CopySize = *BufferSize;
    }
  } else {
    //
    // Callee allocated buffer.  Allocate buffer and return size.
    //
    *Buffer = AllocatePool (CopySize);
    if (*Buffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto GetSection_Done;
    }
  }
  CopyMem (*Buffer, CopyBuffer, CopySize);
  *BufferSize = SectionSize;
  
GetSection_Done:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Worker function.  Destructor for child nodes.

  @param ChildNode           Indicates the node to destroy

**/
VOID
FreeChildNode (
  IN  FRAMEWORK_SECTION_CHILD_NODE                   *ChildNode
  )
{
  ASSERT (ChildNode->Signature == FRAMEWORK_SECTION_CHILD_SIGNATURE);
  //
  // Remove the child from it's list
  //
  RemoveEntryList (&ChildNode->Link);
  
  if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
    //
    // If it's an encapsulating section, we close the resulting section stream.
    // CloseSectionStream will free all memory associated with the stream.
    //
    CloseSectionStream (&mSectionExtraction, ChildNode->EncapsulatedStreamHandle);
  }
  //
  // Last, free the child node itself
  //
  FreePool (ChildNode);
}  

/**
  SEP member function.  Deletes an existing section stream

  @param This                   Indicates the calling context.
  @param StreamHandleToClose    Indicates the stream to close

  @retval EFI_SUCCESS           Section stream was closed successfully.
  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
  @retval EFI_INVALID_PARAMETER Section stream does not end concident with end of
                                last section.

**/
EFI_STATUS
EFIAPI
CloseSectionStream (
  IN  EFI_SECTION_EXTRACTION_PROTOCOL           *This,
  IN  UINTN                                     StreamHandleToClose
  )
{
  FRAMEWORK_SECTION_STREAM_NODE                      *StreamNode;
  EFI_TPL                                       OldTpl;
  EFI_STATUS                                    Status;
  LIST_ENTRY                                    *Link;
  FRAMEWORK_SECTION_CHILD_NODE                       *ChildNode;
  
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  
  //
  // Locate target stream
  //
  Status = FindStreamNode (StreamHandleToClose, &StreamNode);
  if (!EFI_ERROR (Status)) {
    //
    // Found the stream, so close it
    //
    RemoveEntryList (&StreamNode->Link);
    while (!IsListEmpty (&StreamNode->Children)) {
      Link = GetFirstNode (&StreamNode->Children);
      ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);
      FreeChildNode (ChildNode);
    }
    FreePool (StreamNode->StreamBuffer);
    FreePool (StreamNode);
    Status = EFI_SUCCESS;
  } else {
    Status = EFI_INVALID_PARAMETER;
  }
  
  gBS->RestoreTPL (OldTpl);
  return Status;
}
