EtwpSwitchBuffer

INT64 __fastcall EtwpSwitchBuffer(
        _WMI_LOGGER_CONTEXT *LoggerContext,
        _WMI_BUFFER_HEADER *Buffer,
        _EX_FAST_REF *FastRef,
        UINT64 ProcessorIndex,
        UINT64 Flags){
  __int16 v5; 
  int v6; 
  __int64 v10; 
  __int64 v11; 
  __int64 v12; 
  signed __int64 i; 
  __int64 v14; 
  signed __int64 v15; 
  unsigned __int64 v17; 
  v5 = ProcessorIndex;
  v6 = *((_DWORD *)LoggerContext + 3) & 0x400;
  LODWORD(v10) = EtwpDequeueFreeBuffer(LoggerContext);
  v11 = v10;
  if( v10 )
  {
LABEL_7:
    if( (*((_DWORD *)LoggerContext + 3) & 0x10000000) == 0 )
      *(_WORD *)(v11 + 40) = v5;
    _InterlockedExchangeAdd((volatile signed __int32 *)(v11 + 12), 0xFu);
    while( 1 )
    {
      if( !v6 )
        *(_QWORD *)(v11 + 32) = Buffer;
      _m_prefetchw(FastRef);
      for( i = FastRef->Value; ((unsigned __int64)Buffer ^ i) <= 0xF; i = v15 )
      {
        v14 = v11 | 0xF;
        if( !v11 )
          v14 = 0i64;
        v15 = _InterlockedCompareExchange64((volatile signed __int64 *)FastRef, v14, i);
        if( i == v15 )
          break;
      }
      v17 = i & 0xFFFFFFFFFFFFFFF0ui64;
      if( (_WMI_BUFFER_HEADER *)(i & 0xFFFFFFFFFFFFFFF0ui64) == Buffer )
        break;
      if( v17 )
      {
        if( Buffer )
          _InterlockedDecrement(&Buffer->ReferenceCount);
        _InterlockedExchangeAdd((volatile signed __int32 *)(v11 + 12), 0xFFFFFFF1);
        if( v6 )
          EtwpEnqueueOverflowBuffer((__int64)LoggerContext, v11);
        else
          EtwpEnqueueAvailableBuffer((INT64)LoggerContext, (UINT64 *)v11, 0i64);
        return 0i64;
      }
      if( Buffer )
        _InterlockedDecrement(&Buffer->ReferenceCount);
      Buffer = 0i64;
    }
    if( v17 )
    {
      EtwpPrepareDirtyBuffer((PSTR)LoggerContext, i & 0xFFFFFFFFFFFFFFF0ui64);
      _InterlockedExchangeAdd((volatile signed __int32 *)(v17 + 12), ~(i & 0xF));
      if( !v6 && EtwpBuffersFlushRequired(LoggerContext) )
      {
        if( (Flags & 0x600) != 0 || ObGetCurrentIrql() > 2u )
        {
          if( !_interlockedbittestandset((volatile signed __int32 *)LoggerContext + 209, 8u) )
            KeInsertQueueDpc((PRKDPC)((char *)LoggerContext + 584), 0i64, 0i64);
        }
        else
        {
          KeSetEvent((PRKEVENT)((char *)LoggerContext + 496), 0);
        }
      }
    }
    else if( *((_DWORD *)LoggerContext + 56) )
    {
      EtwpRequestFlushTimer((__int64)LoggerContext, (Flags & 0x600) != 0);
    }
    return 0i64;
  }
  else
  {
    while( (Flags & 0x200) == 0
         && ObGetCurrentIrql() <= 2u
         && (*((_DWORD *)LoggerContext + 3) & 0x40000) == 0
         && (unsigned int)EtwpAllocateFreeBuffers((__int64)LoggerContext, 1u) == 1 )
    {
      LODWORD(v12) = EtwpDequeueFreeBuffer(LoggerContext);
      v11 = v12;
      if( v12 )
        goto LABEL_7;
    }
    if( Buffer )
      _InterlockedDecrement(&Buffer->ReferenceCount);
    return 3221225495i64;
  }
}

Referenced by:

EtwpReserveTraceBuffer