From de4e6bf9631b0b34350fa6b8462f52c81263e87e Mon Sep 17 00:00:00 2001
From: qhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Date: Thu, 28 Aug 2008 02:53:16 +0000
Subject: Fix several approved code review comments: 1. Remove internal
 function prototypes to avoid sync efforts. The layout of them have been
 adjusted 2. Apply macro ALIGN_POINTER to get next section stream 3. Fix a
 potential memory leak issue. 4. Make the comparison between type UINTN and 0
 consistent between one function.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5747 6f19259b-4bc3-4df7-8a09-765794883524
---
 .../Dxe/SectionExtraction/CoreSectionExtraction.c  | 1154 ++++++++------------
 1 file changed, 483 insertions(+), 671 deletions(-)

(limited to 'MdeModulePkg/Core')

diff --git a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
index a7a4509bb1..c8484d45d4 100644
--- a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
+++ b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c
@@ -95,191 +95,6 @@ typedef struct {
 } RPN_EVENT_CONTEXT;
 
 
-
-//
-// Local prototypes
-//
-/**
-  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 CORE_SECTION_STREAM_NODE *Stream,
-  IN CORE_SECTION_CHILD_NODE  *Child,
-  IN EFI_SECTION_TYPE         SearchType,
-  IN EFI_GUID                 *SectionDefinitionGuid
-  );
-
-
-/**
-  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 CORE_SECTION_STREAM_NODE                  **FoundStream
-  );
-
-
-/**
-  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.
-                                 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     CORE_SECTION_STREAM_NODE                   *SourceStream,
-  IN     EFI_SECTION_TYPE                           SearchType,
-  IN OUT UINTN                                      *SectionInstance,
-  IN     EFI_GUID                                   *SectionDefinitionGuid,
-  OUT    CORE_SECTION_CHILD_NODE                    **FoundChild,
-  OUT    CORE_SECTION_STREAM_NODE                   **FoundStream,
-  OUT    UINT32                                     *AuthenticationStatus
-  );
-
-
-/**
-  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.
-                                 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     CORE_SECTION_STREAM_NODE              *Stream,
-  IN     UINT32                                ChildOffset,
-     OUT CORE_SECTION_CHILD_NODE               **ChildNode
-  );
-
-
-/**
-  Worker function.  Destructor for child nodes.
-
-  @param  ChildNode              Indicates the node to destroy
-
-**/
-VOID
-FreeChildNode (
-  IN  CORE_SECTION_CHILD_NODE                   *ChildNode
-  );
-
-
-/**
-  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. AuthenticationStatus- Indicates the
-                                 default authentication status for the new
-                                 stream.
-  @param  AuthenticationStatus   A pointer to a caller-allocated UINT32 that
-                                 indicates the authentication status of the
-                                 output buffer. If the input section's
-                                 GuidedSectionHeader.Attributes field
-                                 has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID
-                                 bit as clear, AuthenticationStatus must return
-                                 zero. Both local bits (19:16) and aggregate
-                                 bits (3:0) in AuthenticationStatus are returned
-                                 by ExtractSection(). These bits reflect the
-                                 status of the extraction operation. The bit
-                                 pattern in both regions must be the same, as
-                                 the local and aggregate authentication statuses
-                                 have equivalent meaning at this level. If the
-                                 function returns anything other than
-                                 EFI_SUCCESS, the value of *AuthenticationStatus
-                                 is undefined.
-  @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
-  );
-
-
-/**
-  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
-  );
-
-
 /**
   The ExtractSection() function processes the input section and
   allocates a buffer from the pool in which it returns the section
@@ -431,247 +246,196 @@ InitializeSectionExtraction (
 
 
 /**
-  SEP member function.  This function creates and returns a new section stream
-  handle to represent the new section stream.
+  Check if a stream is valid.
 
-  @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.
+  @param  SectionStream          The section stream to be checked
+  @param  SectionStreamLength    The length of section stream
 
-  @retval EFI_SUCCESS            The section stream is created successfully.
-  @retval EFI_OUT_OF_RESOURCES   memory allocation failed.
-  @retval EFI_INVALID_PARAMETER  Section stream does not end concident with end
-                                 of last section.
+  @return A boolean value indicating the validness of the section stream.
 
 **/
-EFI_STATUS
-EFIAPI
-OpenSectionStream (
-  IN     UINTN                                     SectionStreamLength,
-  IN     VOID                                      *SectionStream,
-     OUT UINTN                                     *SectionStreamHandle
+BOOLEAN
+IsValidSectionStream (
+  IN  VOID              *SectionStream,
+  IN  UINTN             SectionStreamLength
   )
 {
-  //
-  // Check to see section stream looks good...
-  //
-  if (!IsValidSectionStream (SectionStream, SectionStreamLength)) {
-    return EFI_INVALID_PARAMETER;
+  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;
   }
 
-  return OpenSectionStreamEx (
-           SectionStreamLength,
-           SectionStream,
-           TRUE,
-           0,
-           SectionStreamHandle
-           );
+  ASSERT (FALSE);
+  return FALSE;
 }
 
 
 /**
-  SEP member function.  Retrieves requested section from section stream.
+  Worker function.  Constructor for section streams.
 
-  @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  A pointer to a caller-allocated UINT32 that
-                                indicates the authentication status of the
-                                output buffer. If the input section's
-                                GuidedSectionHeader.Attributes field
-                                has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID
-                                bit as clear, AuthenticationStatus must return
-                                zero. Both local bits (19:16) and aggregate
-                                bits (3:0) in AuthenticationStatus are returned
-                                by ExtractSection(). These bits reflect the
-                                status of the extraction operation. The bit
-                                pattern in both regions must be the same, as
-                                the local and aggregate authentication statuses
-                                have equivalent meaning at this level. If the
-                                function returns anything other than
-                                EFI_SUCCESS, the value of *AuthenticationStatus
-                                is undefined.
+  @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. AuthenticationStatus- Indicates the
+                                 default authentication status for the new
+                                 stream.
+  @param  AuthenticationStatus   A pointer to a caller-allocated UINT32 that
+                                 indicates the authentication status of the
+                                 output buffer. If the input section's
+                                 GuidedSectionHeader.Attributes field
+                                 has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID
+                                 bit as clear, AuthenticationStatus must return
+                                 zero. Both local bits (19:16) and aggregate
+                                 bits (3:0) in AuthenticationStatus are returned
+                                 by ExtractSection(). These bits reflect the
+                                 status of the extraction operation. The bit
+                                 pattern in both regions must be the same, as
+                                 the local and aggregate authentication statuses
+                                 have equivalent meaning at this level. If the
+                                 function returns anything other than
+                                 EFI_SUCCESS, the value of *AuthenticationStatus
+                                 is undefined.
+  @param  SectionStreamHandle    A pointer to a caller allocated section stream
+                                 handle.
 
-  @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 section contents
-                                are truncated.
+  @retval EFI_SUCCESS            Stream was added to stream database.
+  @retval EFI_OUT_OF_RESOURCES   memory allocation failed.
 
 **/
 EFI_STATUS
-EFIAPI
-GetSection (
-  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
+OpenSectionStreamEx (
+  IN     UINTN                                     SectionStreamLength,
+  IN     VOID                                      *SectionStream,
+  IN     BOOLEAN                                   AllocateBuffer,
+  IN     UINT32                                    AuthenticationStatus,
+     OUT UINTN                                     *SectionStreamHandle
   )
 {
-  CORE_SECTION_STREAM_NODE                              *StreamNode;
-  EFI_TPL                                               OldTpl;
-  EFI_STATUS                                            Status;
-  CORE_SECTION_CHILD_NODE                               *ChildNode;
-  CORE_SECTION_STREAM_NODE                              *ChildStreamNode;
-  UINTN                                                 CopySize;
-  UINT32                                                ExtractedAuthenticationStatus;
-  UINTN                                                 Instance;
-  UINT8                                                 *CopyBuffer;
-  UINTN                                                 SectionSize;
-
-
-  OldTpl = CoreRaiseTpl (TPL_NOTIFY);
-  Instance = SectionInstance + 1;
-
-  //
-  // Locate target stream
-  //
-  Status = FindStreamNode (SectionStreamHandle, &StreamNode);
-  if (EFI_ERROR (Status)) {
-    Status = EFI_INVALID_PARAMETER;
-    goto GetSection_Done;
-  }
+  CORE_SECTION_STREAM_NODE    *NewStream;
+  EFI_TPL                     OldTpl;
 
   //
-  // Found the stream, now locate and return the appropriate section
+  // Allocate a new stream
   //
-  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;
-    }
-    CopySize = ChildNode->Size - sizeof (EFI_COMMON_SECTION_HEADER);
-    CopyBuffer = ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream + sizeof (EFI_COMMON_SECTION_HEADER);
-    *AuthenticationStatus = ExtractedAuthenticationStatus;
+  NewStream = AllocatePool (sizeof (CORE_SECTION_STREAM_NODE));
+  if (NewStream == NULL) {
+    return EFI_OUT_OF_RESOURCES;
   }
 
-  SectionSize = CopySize;
-  if (*Buffer != NULL) {
+  if (AllocateBuffer) {
     //
-    // Caller allocated buffer.  Fill to size and return required size...
+    // if we're here, we're double buffering, allocate the buffer and copy the
+    // data in
     //
-    if (*BufferSize < CopySize) {
-      Status = EFI_WARN_BUFFER_TOO_SMALL;
-      CopySize = *BufferSize;
+    if (SectionStreamLength > 0) {
+      NewStream->StreamBuffer = AllocatePool (SectionStreamLength);
+      if (NewStream->StreamBuffer == NULL) {
+        CoreFreePool (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 {
     //
-    // Callee allocated buffer.  Allocate buffer and return size.
+    // 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.
     //
-    *Buffer = AllocatePool (CopySize);
-    if (*Buffer == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-      goto GetSection_Done;
-    }
+    NewStream->StreamBuffer = SectionStream;
   }
-  CopyMem (*Buffer, CopyBuffer, CopySize);
-  *BufferSize = SectionSize;
 
-GetSection_Done:
+  //
+  // Initialize the rest of the section stream
+  //
+  NewStream->Signature = CORE_SECTION_STREAM_SIGNATURE;
+  NewStream->StreamHandle = (UINTN) NewStream;
+  NewStream->StreamLength = SectionStreamLength;
+  InitializeListHead (&NewStream->Children);
+  NewStream->AuthenticationStatus = AuthenticationStatus;
+
+  //
+  // Add new stream to stream list
+  //
+  OldTpl = CoreRaiseTpl (TPL_NOTIFY);
+  InsertTailList (&mStreamRoot, &NewStream->Link);
   CoreRestoreTpl (OldTpl);
 
-  return Status;
-}
+  *SectionStreamHandle = NewStream->StreamHandle;
 
+  return EFI_SUCCESS;
+}
 
 
 /**
-  SEP member function.  Deletes an existing section stream
+  SEP member function.  This function creates and returns a new section stream
+  handle to represent the new section stream.
 
-  @param  StreamHandleToClose    Indicates the stream to close
+  @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            The section stream is closed sucessfully.
-  @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.
+  @retval EFI_SUCCESS            The section stream is created 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  UINTN                                     StreamHandleToClose
+OpenSectionStream (
+  IN     UINTN                                     SectionStreamLength,
+  IN     VOID                                      *SectionStream,
+     OUT UINTN                                     *SectionStreamHandle
   )
 {
-  CORE_SECTION_STREAM_NODE                      *StreamNode;
-  EFI_TPL                                       OldTpl;
-  EFI_STATUS                                    Status;
-  LIST_ENTRY                                    *Link;
-  CORE_SECTION_CHILD_NODE                       *ChildNode;
-
-  OldTpl = CoreRaiseTpl (TPL_NOTIFY);
-
   //
-  // Locate target stream
+  // Check to see section stream looks good...
   //
-  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);
-    }
-    CoreFreePool (StreamNode->StreamBuffer);
-    CoreFreePool (StreamNode);
-    Status = EFI_SUCCESS;
-  } else {
-    Status = EFI_INVALID_PARAMETER;
+  if (!IsValidSectionStream (SectionStream, SectionStreamLength)) {
+    return EFI_INVALID_PARAMETER;
   }
 
-  CoreRestoreTpl (OldTpl);
-  return Status;
+  return OpenSectionStreamEx (
+           SectionStreamLength,
+           SectionStream,
+           TRUE,
+           0,
+           SectionStreamHandle
+           );
 }
 
 
@@ -715,161 +479,6 @@ ChildIsType (
 }
 
 
-/**
-  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.
-                                 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     CORE_SECTION_STREAM_NODE                   *SourceStream,
-  IN     EFI_SECTION_TYPE                           SearchType,
-  IN OUT UINTN                                      *SectionInstance,
-  IN     EFI_GUID                                   *SectionDefinitionGuid,
-  OUT    CORE_SECTION_CHILD_NODE                    **FoundChild,
-  OUT    CORE_SECTION_STREAM_NODE                   **FoundStream,
-  OUT    UINT32                                     *AuthenticationStatus
-  )
-{
-  CORE_SECTION_CHILD_NODE                       *CurrentChildNode;
-  CORE_SECTION_CHILD_NODE                       *RecursedChildNode;
-  CORE_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;
-      }
-    }
-
-    if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
-      //
-      // If the current node is an encapsulating node, recurse into it...
-      //
-      Status = FindChildNode (
-                (CORE_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.  Constructor for new child nodes.
 
@@ -1123,143 +732,160 @@ CreateChildNode (
 
 
 /**
-  Worker function.  Destructor for child nodes.
+  Worker function  Recursively searches / builds section stream database
+  looking for requested section.
 
-  @param  ChildNode              Indicates the node to destroy
+  @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.
+                                 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
 
 **/
-VOID
-FreeChildNode (
-  IN  CORE_SECTION_CHILD_NODE                   *ChildNode
+EFI_STATUS
+FindChildNode (
+  IN     CORE_SECTION_STREAM_NODE                   *SourceStream,
+  IN     EFI_SECTION_TYPE                           SearchType,
+  IN OUT UINTN                                      *SectionInstance,
+  IN     EFI_GUID                                   *SectionDefinitionGuid,
+  OUT    CORE_SECTION_CHILD_NODE                    **FoundChild,
+  OUT    CORE_SECTION_STREAM_NODE                   **FoundStream,
+  OUT    UINT32                                     *AuthenticationStatus
   )
 {
-  ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE);
-  //
-  // Remove the child from it's list
-  //
-  RemoveEntryList (&ChildNode->Link);
+  CORE_SECTION_CHILD_NODE                       *CurrentChildNode;
+  CORE_SECTION_CHILD_NODE                       *RecursedChildNode;
+  CORE_SECTION_STREAM_NODE                      *RecursedFoundStream;
+  UINT32                                        NextChildOffset;
+  EFI_STATUS                                    ErrorStatus;
+  EFI_STATUS                                    Status;
 
-  if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
+  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)) {
     //
-    // If it's an encapsulating section, we close the resulting section stream.
-    // CloseSectionStream will free all memory associated with the stream.
+    // 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.
     //
-    CloseSectionStream (ChildNode->EncapsulatedStreamHandle);
+    Status = CreateChildNode (SourceStream, 0, &CurrentChildNode);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
   }
+
   //
-  // Last, free the child node itself
+  // 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
   //
-  CoreFreePool (ChildNode);
-}
-
-
+  CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetFirstNode(&SourceStream->Children));
 
-/**
-  Worker function.  Constructor for section streams.
+  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;
+      }
+    }
 
-  @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. AuthenticationStatus- Indicates the
-                                 default authentication status for the new
-                                 stream.
-  @param  AuthenticationStatus   A pointer to a caller-allocated UINT32 that
-                                 indicates the authentication status of the
-                                 output buffer. If the input section's
-                                 GuidedSectionHeader.Attributes field
-                                 has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID
-                                 bit as clear, AuthenticationStatus must return
-                                 zero. Both local bits (19:16) and aggregate
-                                 bits (3:0) in AuthenticationStatus are returned
-                                 by ExtractSection(). These bits reflect the
-                                 status of the extraction operation. The bit
-                                 pattern in both regions must be the same, as
-                                 the local and aggregate authentication statuses
-                                 have equivalent meaning at this level. If the
-                                 function returns anything other than
-                                 EFI_SUCCESS, the value of *AuthenticationStatus
-                                 is undefined.
-  @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
-  )
-{
-  CORE_SECTION_STREAM_NODE    *NewStream;
-  EFI_TPL                     OldTpl;
-
-  //
-  // Allocate a new stream
-  //
-  NewStream = AllocatePool (sizeof (CORE_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) {
-        CoreFreePool (NewStream);
-        return EFI_OUT_OF_RESOURCES;
+    if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
+      //
+      // If the current node is an encapsulating node, recurse into it...
+      //
+      Status = FindChildNode (
+                (CORE_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)) {
       //
-      // Copy in stream data
+      // 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..
       //
-      CopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength);
+      CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetNextNode (&SourceStream->Children, &CurrentChildNode->Link));
     } else {
       //
-      // It's possible to have a zero length section stream.
+      // 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.
       //
-      NewStream->StreamBuffer = NULL;
+      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;
+      }
     }
-  } 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 = CORE_SECTION_STREAM_SIGNATURE;
-  NewStream->StreamHandle = (UINTN) NewStream;
-  NewStream->StreamLength = SectionStreamLength;
-  InitializeListHead (&NewStream->Children);
-  NewStream->AuthenticationStatus = AuthenticationStatus;
-
-  //
-  // Add new stream to stream list
-  //
-  OldTpl = CoreRaiseTpl (TPL_NOTIFY);
-  InsertTailList (&mStreamRoot, &NewStream->Link);
-  CoreRestoreTpl (OldTpl);
-
-  *SectionStreamHandle = NewStream->StreamHandle;
-
-  return EFI_SUCCESS;
 }
 
 
-
 /**
   Worker function.  Search stream database for requested stream handle.
 
@@ -1299,52 +925,237 @@ FindStreamNode (
 
 
 /**
-  Check if a stream is valid.
+  SEP member function.  Retrieves requested section from section stream.
 
-  @param  SectionStream          The section stream to be checked
-  @param  SectionStreamLength    The length of section stream
+  @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  A pointer to a caller-allocated UINT32 that
+                                indicates the authentication status of the
+                                output buffer. If the input section's
+                                GuidedSectionHeader.Attributes field
+                                has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID
+                                bit as clear, AuthenticationStatus must return
+                                zero. Both local bits (19:16) and aggregate
+                                bits (3:0) in AuthenticationStatus are returned
+                                by ExtractSection(). These bits reflect the
+                                status of the extraction operation. The bit
+                                pattern in both regions must be the same, as
+                                the local and aggregate authentication statuses
+                                have equivalent meaning at this level. If the
+                                function returns anything other than
+                                EFI_SUCCESS, the value of *AuthenticationStatus
+                                is undefined.
 
-  @return A boolean value indicating the validness of the section stream.
+  @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 section contents
+                                are truncated.
 
 **/
-BOOLEAN
-IsValidSectionStream (
-  IN  VOID              *SectionStream,
-  IN  UINTN             SectionStreamLength
+EFI_STATUS
+EFIAPI
+GetSection (
+  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
   )
 {
-  UINTN                       TotalLength;
-  UINTN                       SectionLength;
-  EFI_COMMON_SECTION_HEADER   *SectionHeader;
-  EFI_COMMON_SECTION_HEADER   *NextSectionHeader;
+  CORE_SECTION_STREAM_NODE                              *StreamNode;
+  EFI_TPL                                               OldTpl;
+  EFI_STATUS                                            Status;
+  CORE_SECTION_CHILD_NODE                               *ChildNode;
+  CORE_SECTION_STREAM_NODE                              *ChildStreamNode;
+  UINTN                                                 CopySize;
+  UINT32                                                ExtractedAuthenticationStatus;
+  UINTN                                                 Instance;
+  UINT8                                                 *CopyBuffer;
+  UINTN                                                 SectionSize;
 
-  TotalLength = 0;
-  SectionHeader = (EFI_COMMON_SECTION_HEADER *)SectionStream;
 
-  while (TotalLength < SectionStreamLength) {
-    SectionLength = SECTION_SIZE (SectionHeader);
-    TotalLength += SectionLength;
+  OldTpl = CoreRaiseTpl (TPL_NOTIFY);
+  Instance = SectionInstance + 1;
 
-    if (TotalLength == SectionStreamLength) {
-      return TRUE;
+  //
+  // 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;
     }
+    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) {
     //
-    // Move to the next byte following the section...
+    // Caller allocated buffer.  Fill to size and return required size...
     //
-    SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength);
+    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:
+  CoreRestoreTpl (OldTpl);
+
+  return Status;
+}
+
+
+/**
+  Worker function.  Destructor for child nodes.
+
+  @param  ChildNode              Indicates the node to destroy
 
+**/
+VOID
+FreeChildNode (
+  IN  CORE_SECTION_CHILD_NODE                   *ChildNode
+  )
+{
+  ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE);
+  //
+  // Remove the child from it's list
+  //
+  RemoveEntryList (&ChildNode->Link);
+
+  if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
     //
-    // Figure out where the next section begins
+    // If it's an encapsulating section, we close the resulting section stream.
+    // CloseSectionStream will free all memory associated with the stream.
     //
-    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) SectionHeader + 3);
-    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader & ~(UINTN)3);
-    TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader;
-    SectionHeader = NextSectionHeader;
+    CloseSectionStream (ChildNode->EncapsulatedStreamHandle);
   }
+  //
+  // Last, free the child node itself
+  //
+  CoreFreePool (ChildNode);
+}
 
-  ASSERT (FALSE);
-  return FALSE;
+
+/**
+  SEP member function.  Deletes an existing section stream
+
+  @param  StreamHandleToClose    Indicates the stream to close
+
+  @retval EFI_SUCCESS            The section stream is closed sucessfully.
+  @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  UINTN                                     StreamHandleToClose
+  )
+{
+  CORE_SECTION_STREAM_NODE                      *StreamNode;
+  EFI_TPL                                       OldTpl;
+  EFI_STATUS                                    Status;
+  LIST_ENTRY                                    *Link;
+  CORE_SECTION_CHILD_NODE                       *ChildNode;
+
+  OldTpl = CoreRaiseTpl (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);
+    }
+    CoreFreePool (StreamNode->StreamBuffer);
+    CoreFreePool (StreamNode);
+    Status = EFI_SUCCESS;
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  CoreRestoreTpl (OldTpl);
+  return Status;
 }
 
 
@@ -1469,7 +1280,7 @@ CustomGuidedSectionExtract (
     return Status;
   }
 
-  if (ScratchBufferSize != 0) {
+  if (ScratchBufferSize > 0) {
     //
     // Allocate scratch buffer
     //
@@ -1485,6 +1296,7 @@ CustomGuidedSectionExtract (
     //
     AllocatedOutputBuffer = AllocatePool (OutputBufferSize);
     if (AllocatedOutputBuffer == NULL) {
+      FreePool (ScratchBuffer);
       return EFI_OUT_OF_RESOURCES;
     }
     *OutputBuffer = AllocatedOutputBuffer;
-- 
cgit v1.2.3