summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Core/Dxe
diff options
context:
space:
mode:
authorqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>2008-08-28 02:53:16 +0000
committerqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>2008-08-28 02:53:16 +0000
commitde4e6bf9631b0b34350fa6b8462f52c81263e87e (patch)
treec8768ff6509a50d1bd8cc5ad267f465ea84be361 /MdeModulePkg/Core/Dxe
parent89963a827ed0db565d8fb80c7ee2b81a3d1c3309 (diff)
downloadedk2-platforms-de4e6bf9631b0b34350fa6b8462f52c81263e87e.tar.xz
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
Diffstat (limited to 'MdeModulePkg/Core/Dxe')
-rw-r--r--MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c1154
1 files changed, 483 insertions, 671 deletions
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
+ );
}
@@ -716,161 +480,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.
@param Stream Indicates the section stream in which to add the
@@ -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
- //
- CoreFreePool (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
- )
-{
- CORE_SECTION_STREAM_NODE *NewStream;
- EFI_TPL OldTpl;
//
- // Allocate a new stream
+ // 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
//
- NewStream = AllocatePool (sizeof (CORE_SECTION_STREAM_NODE));
- if (NewStream == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
+ CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetFirstNode(&SourceStream->Children));
- 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;
+ 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) {
//
- // Copy in stream data
+ // If the current node is an encapsulating node, recurse into it...
//
- CopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength);
+ 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 {
//
- // 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;