EFI_SIGNATURE_16 -> SIGNATURE_16 EFI_SIGNATURE_32 -> SIGNATURE_32 EFI_SIGNATURE_64 -> SIGNATURE_64 EFI_FIELD_OFFSET -> OFFSET_OF EFI_MAX_BIT -> MAX_BIT EFI_MAX_ADDRESS -> MAX_ADDRESS These macros are not defined in UEFI spec. It makes more sense to use the equivalent macros in Base.h to avoid alias. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7050 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			420 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			420 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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 - 2008, 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.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #ifndef _SECION_EXTRACTION_H_
 | |
| #define _SECION_EXTRACTION_H_
 | |
| 
 | |
| #include <FrameworkDxe.h>
 | |
| 
 | |
| #include <Protocol/SectionExtraction.h>
 | |
| 
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/UefiLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Protocol/Decompress.h>
 | |
| #include <Protocol/GuidedSectionExtraction.h>
 | |
| 
 | |
| //
 | |
| // Local defines and typedefs
 | |
| //
 | |
| #define CORE_SECTION_CHILD_SIGNATURE  SIGNATURE_32('S','X','C','S')
 | |
| #define CHILD_SECTION_NODE_FROM_LINK(Node) \
 | |
|   CR (Node, CORE_SECTION_CHILD_NODE, Link, CORE_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;
 | |
| } CORE_SECTION_CHILD_NODE;
 | |
| 
 | |
| #define CORE_SECTION_STREAM_SIGNATURE SIGNATURE_32('S','X','S','S')
 | |
| #define STREAM_NODE_FROM_LINK(Node) \
 | |
|   CR (Node, CORE_SECTION_STREAM_NODE, Link, CORE_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;
 | |
| } CORE_SECTION_STREAM_NODE;
 | |
| 
 | |
| #define NULL_STREAM_HANDLE    0
 | |
| 
 | |
| typedef struct {
 | |
|   CORE_SECTION_CHILD_NODE     *ChildNode;
 | |
|   CORE_SECTION_STREAM_NODE    *ParentStream;
 | |
|   VOID                        *Registration;
 | |
|   EFI_EVENT                   Event;
 | |
| } RPN_EVENT_CONTEXT;
 | |
|   
 | |
|   
 | |
| /**
 | |
|   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
 | |
| CoreCreateProtocolNotifyEvent (
 | |
|   IN EFI_GUID             *ProtocolGuid,
 | |
|   IN EFI_TPL              NotifyTpl,
 | |
|   IN EFI_EVENT_NOTIFY     NotifyFunction,
 | |
|   IN VOID                 *NotifyContext,
 | |
|   OUT VOID                **Registration,
 | |
|   IN  BOOLEAN             SignalFlag
 | |
|   );
 | |
| 
 | |
| //
 | |
| // 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
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   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
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   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 CORE_SECTION_STREAM_NODE       *ParentStream,
 | |
|   IN CORE_SECTION_CHILD_NODE        *ChildNode
 | |
|   );
 | |
| 
 | |
| /**
 | |
|   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
 | |
|   );
 | |
|   
 | |
| /**
 | |
|   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.
 | |
|   @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     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.
 | |
|   @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     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.
 | |
|   @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
 | |
|   );
 | |
|   
 | |
| /**
 | |
| 
 | |
|   Check if a stream is valid.
 | |
| 
 | |
|   @param SectionStream         The section stream to be checked
 | |
|   @param SectionStreamLength   The length of section stream
 | |
| 
 | |
|   @return The validness of a stream.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| IsValidSectionStream (
 | |
|   IN  VOID              *SectionStream,
 | |
|   IN  UINTN             SectionStreamLength
 | |
|   );
 | |
| 
 | |
| #endif  // _SECTION_EXTRACTION_H_
 |