EtwpSwitchBuffer

NTSTATUS __stdcall EtwpSwitchBuffer(
        _WMI_LOGGER_CONTEXT *LoggerContext,
        _WMI_BUFFER_HEADER *Buffer,
        _EX_FAST_REF *FastRef,
        UINT64 ProcessorIndex,
        UINT64 Flags){
  __int16 v5; 
  unsigned int v6; 
  _WMI_BUFFER_HEADER *v10; 
  signed __int64 i; 
  signed __int64 v12; 
  unsigned __int64 v14; 

  v5 = ProcessorIndex;
  v6 = LoggerContext->LoggerMode & 0x400;
  v10 = EtwpDequeueFreeBuffer(LoggerContext);
  if( v10 )
  {
LABEL_7:
    if( (LoggerContext->LoggerMode & 0x10000000) == 0 )
      *((_WORD *)v10 + 20) = v5;
    _InterlockedExchangeAdd((volatile signed __int32 *)v10 + 3, 0xFu);
    while( 1 )
    {
      if( !v6 )
        *((_QWORD *)v10 + 4) = Buffer;
      _m_prefetchw(FastRef);
      for( i = FastRef->Value; ((unsigned __int64)Buffer ^ i) <= 0xF; i = v12 )
      {
        v12 = _InterlockedCompareExchange64((volatile signed __int64 *)FastRef, (unsigned __int64)v10 | 0xF, i);
        if( i == v12 )
          break;
      }
      v14 = i & 0xFFFFFFFFFFFFFFF0ui64;
      if( (_WMI_BUFFER_HEADER *)(i & 0xFFFFFFFFFFFFFFF0ui64) == Buffer )
        break;
      if( v14 )
      {
        if( Buffer )
          _InterlockedDecrement((volatile signed __int32 *)Buffer + 3);
        _InterlockedExchangeAdd((volatile signed __int32 *)v10 + 3, 0xFFFFFFF1);
        if( v6 )
          EtwpEnqueueOverflowBuffer(LoggerContext, v10);
        else
          EtwpEnqueueAvailableBuffer(LoggerContext, v10, EtwBufferStateFree);
        return 0;
      }
      if( Buffer )
        _InterlockedDecrement((volatile signed __int32 *)Buffer + 3);
      Buffer = 0i64;
    }
    if( v14 )
    {
      EtwpPrepareDirtyBuffer(LoggerContext, (_WMI_BUFFER_HEADER *)(i & 0xFFFFFFFFFFFFFFF0ui64));
      _InterlockedExchangeAdd((volatile signed __int32 *)(v14 + 12), ~(i & 0xF));
      if( !v6 && EtwpBuffersFlushRequired((INT64)LoggerContext) )
      {
        if( (Flags & 0x600) != 0 || ObGetCurrentIrql() > 2u )
        {
          if( !_interlockedbittestandset((volatile signed __int32 *)&LoggerContext->836, 8u) )
            KeInsertQueueDpc((UINT64)&LoggerContext->LoggerDpc, 0i64, 0i64);
        }
        else
        {
          KeSetEvent((PRKEVENT)&LoggerContext->gap1D4[28], 0, 0);
        }
      }
    }
    else if( LoggerContext->FlushTimer )
    {
      EtwpRequestFlushTimer(LoggerContext, (Flags & 0x600) != 0);
    }
    return 0;
  }
  else
  {
    while( (Flags & 0x200) == 0
         && ObGetCurrentIrql() <= 2u
         && (LoggerContext->LoggerMode & 0x40000) == 0
         && (unsigned int)EtwpAllocateFreeBuffers(LoggerContext, 1ui64) == 1 )
    {
      v10 = EtwpDequeueFreeBuffer(LoggerContext);
      if( v10 )
        goto LABEL_7;
    }
    if( Buffer )
      _InterlockedDecrement((volatile signed __int32 *)Buffer + 3);
    return -1073741801;
  }
}

Referenced by:

EtwpReserveTraceBuffer