mirror of https://github.com/acidanthera/audk.git
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 EFI_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 EFI_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_
|