⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coresectionextraction.c

📁 EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是EFI BIOS源代码中的与平台无关部分的代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  SEP member function.  Retrieves requested section from section stream.

Arguments:  
  This:                 Pointer to SEP instance.
  SectionStreamHandle:  The section stream from which to extract the requested
                          section.
  SectionType:         A pointer to the type of section to search for.
  SectionDefinitionGuid: If the section type is EFI_SECTION_GUID_DEFINED, then
                        SectionDefinitionGuid indicates which of these types
                          of sections to search for.
  SectionInstance:      Indicates which instance of the requested section to
                          return.
  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.
  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.
  AuthenticationStatus: Indicates the authentication status of the retrieved
                          section.

Returns:  
  EFI_SUCCESS:        Section was retrieved successfully
  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.
  EFI_NOT_FOUND:      An error was encountered when parsing the SectionStream.
                        This indicates the SectionStream  is not correctly 
                        formatted.
  EFI_NOT_FOUND:      The requested section does not exist.
  EFI_OUT_OF_RESOURCES: The system has insufficient resources to process the 
                        request.
  EFI_INVALID_PARAMETER: The SectionStreamHandle does not exist.
  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.

--*/
{
  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 (EFI_TPL_NOTIFY);
  Instance = SectionInstance + 1;
  
  //
  // Locate target stream
  //
  Status = FindStreamNode (SectionStreamHandle, &StreamNode);
  if (EFI_ERROR (Status)) {
    Status = EFI_INVALID_PARAMETER;
    goto GetSection_Done;
  }
  
  //
  // Found the stream, now locate and return the appropriate section
  //
  if (SectionType == NULL) {
    //
    // SectionType == NULL means return the WHOLE section stream...
    //
    CopySize = StreamNode->StreamLength;
    CopyBuffer = StreamNode->StreamBuffer;
    *AuthenticationStatus = StreamNode->AuthenticationStatus;
  } else {
    //
    // There's a requested section type, so go find it and return it...
    //
    Status = FindChildNode (
                      StreamNode, 
                      *SectionType, 
                      &Instance, 
                      SectionDefinitionGuid,
                      &ChildNode,
                      &ChildStreamNode, 
                      &ExtractedAuthenticationStatus
                      );
    if (EFI_ERROR (Status)) {
      goto GetSection_Done;
    }
    CopySize = ChildNode->Size - sizeof (EFI_COMMON_SECTION_HEADER);
    CopyBuffer = ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream + sizeof (EFI_COMMON_SECTION_HEADER);
    *AuthenticationStatus = ExtractedAuthenticationStatus;
  }   
    
  SectionSize = CopySize;  
  if (*Buffer != NULL) {
    //
    // Caller allocated buffer.  Fill to size and return required size...
    //
    if (*BufferSize < CopySize) {
      Status = EFI_WARN_BUFFER_TOO_SMALL;
      CopySize = *BufferSize;
    }
  } else {
    //
    // Callee allocated buffer.  Allocate buffer and return size.
    //
    *Buffer = CoreAllocateBootServicesPool (CopySize);
    if (*Buffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto GetSection_Done;
    }
  }
  EfiCommonLibCopyMem (*Buffer, CopyBuffer, CopySize);
  *BufferSize = SectionSize;
  
GetSection_Done:
  CoreRestoreTpl (OldTpl);
  return Status;
}



EFI_STATUS
EFIAPI
CloseSectionStream (
  IN  EFI_SECTION_EXTRACTION_PROTOCOL           *This,
  IN  UINTN                                     StreamHandleToClose
  )
/*++

Routine Description:
  SEP member function.  Deletes an existing section stream

Arguments:
  This                - Indicates the calling context.
  StreamHandleToClose - Indicates the stream to close

Returns:
  EFI_SUCCESS
  EFI_OUT_OF_RESOURCES - memory allocation failed.
  EFI_INVALID_PARAMETER - section stream does not end concident with end of
                          last section.

--*/
{
  CORE_SECTION_STREAM_NODE                      *StreamNode;
  EFI_TPL                                       OldTpl;
  EFI_STATUS                                    Status;
  EFI_LIST                                      *Link;
  CORE_SECTION_CHILD_NODE                       *ChildNode;
  
  OldTpl = CoreRaiseTpl (EFI_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;
}


STATIC
BOOLEAN
ChildIsType (
  IN CORE_SECTION_STREAM_NODE *Stream,
  IN CORE_SECTION_CHILD_NODE  *Child,
  IN EFI_SECTION_TYPE         SearchType,
  IN EFI_GUID                 *SectionDefinitionGuid
  )
/*++

Routine Description:
  Worker function.  Determine if the input stream:child matches the input type.

Arguments:
  Stream              - Indicates the section stream associated with the child
  Child               - Indicates the child to check
  SearchType          - Indicates the type of section to check against for
  SectionDefinitionGuid - Indicates the GUID to check against if the type is
                        EFI_SECTION_GUID_DEFINED
Returns:
  TRUE                - The child matches
  FALSE               - The child doesn't match

--*/
{
  EFI_GUID_DEFINED_SECTION    *GuidedSection;
  
  if (SearchType == EFI_SECTION_ALL) {
    return TRUE;
  }
  if (Child->Type != SearchType) {
    return FALSE;
  }
  if (SearchType != EFI_SECTION_GUID_DEFINED) {
    return TRUE;
  }
  GuidedSection = (EFI_GUID_DEFINED_SECTION * )(Stream->StreamBuffer + Child->OffsetInStream);
  return EfiCompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid);
}


STATIC
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
  )
/*++

Routine Description:
  Worker function  Recursively searches / builds section stream database
  looking for requested section.

Arguments:
  SourceStream        - Indicates the section stream in which to do the search.
  SearchType          - Indicates the type of section to search for.
  SectionInstance     - Indicates which instance of section to find.  This is
                        an in/out parameter to deal with recursions.
  SectionDefinitionGuid  - Guid of section definition
  FoundChild          - Output indicating the child node that is found.
  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.
  AuthenticationStatus- Indicates the authentication status of the found section.

Returns:
  EFI_SUCCESS         - Child node was found and returned.
  EFI_OUT_OF_RESOURCES- Memory allocation failed.
  EFI_NOT_FOUND       - Requested child node does not exist.
  EFI_PROTOCOL_ERROR  - a required GUIDED section extraction protocol does not
                        exist

--*/
{
  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.
    //
    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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -