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

📄 coresectionextraction.c

📁 EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是EFI BIOS源代码中的与平台无关部分的代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  ChildNode           - Indicates the child node that is the encapsulation section.

Returns:
  None

--*/
{
  RPN_EVENT_CONTEXT *Context;
  
  //
  // Allocate new event structure and context
  //
  Context = CoreAllocateBootServicesPool (sizeof (RPN_EVENT_CONTEXT));
  ASSERT (Context != NULL);
  
  Context->ChildNode = ChildNode;
  Context->ParentStream = ParentStream;
 
  Context->Event = CoreCreateProtocolNotifyEvent (
                    Context->ChildNode->EncapsulationGuid,
                    EFI_TPL_NOTIFY,
                    NotifyGuidedExtraction,
                    Context,
                    &Context->Registration,
                    FALSE
                    );
}
  
  
STATIC
VOID
EFIAPI
NotifyGuidedExtraction (
  IN   EFI_EVENT   Event,
  IN   VOID        *RpnContext
  )
/*++

Routine Description:
  RPN callback function.  Removes a stale section stream and re-initializes it
  with an updated AuthenticationStatus.

Arguments:
  Event               - The event that fired
  RpnContext          - A pointer to the context that allows us to identify
                        the relevent encapsulation...

Returns:
  None

--*/
{
  EFI_STATUS                              Status;
  EFI_GUID_DEFINED_SECTION                *GuidedHeader;
  EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL  *GuidedExtraction;
  VOID                                    *NewStreamBuffer;
  UINTN                                   NewStreamBufferSize;
  UINT32                                  AuthenticationStatus;
  RPN_EVENT_CONTEXT                       *Context;
  
  Context = RpnContext;
  
  Status = CloseSectionStream (&mSectionExtraction, Context->ChildNode->EncapsulatedStreamHandle);
  if (!EFI_ERROR (Status)) {
    //
    // The stream closed successfully, so re-open the stream with correct AuthenticationStatus
    //
  
    GuidedHeader = (EFI_GUID_DEFINED_SECTION *) 
      (Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream);
    ASSERT (GuidedHeader->CommonHeader.Type == EFI_SECTION_GUID_DEFINED);
    
    Status = CoreLocateProtocol (Context->ChildNode->EncapsulationGuid, NULL, &GuidedExtraction);
    ASSERT_EFI_ERROR (Status);

    
    Status = GuidedExtraction->ExtractSection (
                                 GuidedExtraction,
                                 GuidedHeader,
                                 &NewStreamBuffer,
                                 &NewStreamBufferSize,
                                 &AuthenticationStatus
                                 );
    ASSERT_EFI_ERROR (Status);
    //
    // OR in the parent stream's aggregagate status.
    //
    AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;
    Status = OpenSectionStreamEx (
               NewStreamBufferSize,
               NewStreamBuffer,
               FALSE,
               AuthenticationStatus,
               &Context->ChildNode->EncapsulatedStreamHandle
               );
    ASSERT_EFI_ERROR (Status);
  }

  //
  //  If above, the stream  did not close successfully, it indicates it's
  //  alread been closed by someone, so just destroy the event and be done with
  //  it.
  //
  
  CoreCloseEvent (Event);
  CoreFreePool (Context);
}  
  

STATIC
VOID
FreeChildNode (
  IN  CORE_SECTION_CHILD_NODE                   *ChildNode
  )
/*++

Routine Description:
  Worker function.  Destructor for child nodes.

Arguments:
  ChildNode           - Indicates the node to destroy

Returns:
  none

--*/
{
  ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE);
  //
  // Remove the child from it's list
  //
  RemoveEntryList (&ChildNode->Link);
  
  if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
    //
    // If it's an encapsulating section, we close the resulting section stream.
    // CloseSectionStream will free all memory associated with the stream.
    //
    CloseSectionStream (&mSectionExtraction, ChildNode->EncapsulatedStreamHandle);
  }
  //
  // Last, free the child node itself
  //
  CoreFreePool (ChildNode);
}  


STATIC
EFI_STATUS
OpenSectionStreamEx (
  IN     UINTN                                     SectionStreamLength,
  IN     VOID                                      *SectionStream,
  IN     BOOLEAN                                   AllocateBuffer,
  IN     UINT32                                    AuthenticationStatus,   
     OUT UINTN                                     *SectionStreamHandle
  )
/*++

  Routine Description:
    Worker function.  Constructor for section streams.

  Arguments:
    SectionStreamLength - Size in bytes of the section stream.
    SectionStream       - Buffer containing the new section stream.
    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.
    SectionStreamHandle - A pointer to a caller allocated section stream handle.

  Returns:
    EFI_SUCCESS         - Stream was added to stream database.
    EFI_OUT_OF_RESOURCES - memory allocation failed.

--*/
{
  CORE_SECTION_STREAM_NODE    *NewStream;
  EFI_TPL                     OldTpl;
  
  //
  // Allocate a new stream
  //
  NewStream = CoreAllocateBootServicesPool (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 = CoreAllocateBootServicesPool (SectionStreamLength); 
      if (NewStream->StreamBuffer == NULL) {
        CoreFreePool (NewStream);
        return EFI_OUT_OF_RESOURCES;
      }
      //
      // Copy in stream data
      //
      EfiCommonLibCopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength);
    } else {
      //
      // It's possible to have a zero length section stream.
      //
      NewStream->StreamBuffer = NULL;
    }
  } 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 (EFI_TPL_NOTIFY);
  InsertTailList (&mStreamRoot, &NewStream->Link);
  CoreRestoreTpl (OldTpl);

  *SectionStreamHandle = NewStream->StreamHandle;
  
  return EFI_SUCCESS;
}


STATIC
EFI_STATUS
FindStreamNode (
  IN  UINTN                                     SearchHandle,
  OUT CORE_SECTION_STREAM_NODE                  **FoundStream
  )
/*++

  Routine Description:
    Worker function.  Search stream database for requested stream handle.

  Arguments:
    SearchHandle        - Indicates which stream to look for.
    FoundStream         - Output pointer to the found stream.

  Returns:
    EFI_SUCCESS         - StreamHandle was found and *FoundStream contains
                          the stream node.
    EFI_NOT_FOUND       - SearchHandle was not found in the stream database.

--*/
{  
  CORE_SECTION_STREAM_NODE                      *StreamNode;
  
  if (!IsListEmpty (&mStreamRoot)) {
    StreamNode = STREAM_NODE_FROM_LINK (GetFirstNode (&mStreamRoot));
    for (;;) {
      if (StreamNode->StreamHandle == SearchHandle) {
        *FoundStream = StreamNode;
        return EFI_SUCCESS;
      } else if (IsNodeAtEnd (&mStreamRoot, &StreamNode->Link)) {
        break;
      } else {
        StreamNode = STREAM_NODE_FROM_LINK (GetNextNode (&mStreamRoot, &StreamNode->Link));
      }
    }
  }
  
  return EFI_NOT_FOUND;
}


STATIC
BOOLEAN
IsValidSectionStream (
  IN  VOID              *SectionStream,
  IN  UINTN             SectionStreamLength
  )
/*++

Routine Description:
  Check if a stream is valid.

Arguments:
  SectionStream         - The section stream to be checked
  SectionStreamLength   - The length of section stream

Returns:
  TRUE
  FALSE

--*/
{
  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 = (EFI_COMMON_SECTION_HEADER *) ((UINTN) SectionHeader + 3);
    NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader & ~(UINTN)3);
    TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader;
    SectionHeader = NextSectionHeader;
  }

  ASSERT (FALSE);
  return FALSE;
}

⌨️ 快捷键说明

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