EtwpReserveTraceBuffer

VOID *__stdcall EtwpReserveTraceBuffer(
        _WMI_LOGGER_CONTEXT *LoggerContext,
        UINT64 RequiredSize,
        _ETW_BUFFER_HANDLE *BufferHandle,
        _LARGE_INTEGER *TimeStamp,
        UINT64 Flags){
  unsigned int BufferSize; 
  __int64 LoggerId; 
  int v10; 
  _ETW_SILO_TRACING_BLOCK *v11; 
  $B90001D19DE6081274E09A4BBDE43C18 *v12; 
  signed __int64 Value; 
  signed __int64 v14; 
  int v15; 
  unsigned __int32 v16; 
  unsigned __int64 GetCpuClock; 
  LONGLONG v18; 
  unsigned __int32 v19; 
  signed __int64 v20; 
  signed __int64 i; 
  signed __int64 v22; 
  VOID *result; 
  int v24; 
  NTSTATUS v25; 
  signed __int64 v26; 
  signed __int64 v27; 
  signed __int64 v28; 
  unsigned __int32 v29; 
  bool v30; 
  __int64 PerformanceCounter; 
  __int64 v32; 
  signed __int64 QuadPart; 
  __int64 v34; 
  UINT64 v35; 
  unsigned int v36; 
  unsigned int v37; 
  unsigned int ProcessorIndex; 
  LONGLONG v39; 
  unsigned __int64 v40; 
  _ETW_LOCK_HANDLE LockHandle; 

  if( LoggerContext->AcceptNewEvents < 0 || (unsigned int)RequiredSize > LoggerContext->MaximumEventSize )
  {
LABEL_40:
    EtwpUpdateEventsLostCount(LoggerContext);
    return 0i64;
  }
  BufferSize = LoggerContext->BufferSize;
  LoggerId = LoggerContext->LoggerId;
  v10 = (RequiredSize + 7) & 0xFFFFFFF8;
  v36 = BufferSize;
  v37 = LoggerContext->LoggerId;
  while( 1 )
  {
    ProcessorIndex = KeGetCurrentPrcb()->Number;
    v11 = &LoggerContext->SiloState->ProcessorBlocks[(unsigned __int64)ProcessorIndex];
    if( (LoggerContext->LoggerMode & 0x10000000) != 0 )
      v12 = &LoggerContext->144;
    else
      v12 = ($B90001D19DE6081274E09A4BBDE43C18 *)&v11->ProcessorBuffers[(unsigned int)LoggerId];
    LockHandle.OldIrql = 0;
    _m_prefetchw(v12);
    Value = v12->CurrentBuffer.Value;
    if( (v12->CurrentBuffer.Value & 0xF) != 0 )
    {
      do
      {
        v14 = _InterlockedCompareExchange64((volatile signed __int64 *)v12, Value - 1, Value);
        if( Value == v14 )
          break;
        Value = v14;
      }
      while( (v14 & 0xF) != 0 );
    }
    if( Value )
    {
      v15 = Value & 0xF;
      if( (Value & 0xF) != 0 )
      {
        Value &= 0xFFFFFFFFFFFFFFF0ui64;
        if( v15 == 1 )
        {
          _InterlockedExchangeAdd((volatile signed __int32 *)(Value + 12), 0xFu);
          _m_prefetchw(v12);
          v26 = v12->CurrentBuffer.Value;
          while( (v26 & 0xF) == 0 )
          {
            if( Value != (v26 & 0xFFFFFFFFFFFFFFF0ui64) )
              break;
            v27 = v26;
            v26 = _InterlockedCompareExchange64((volatile signed __int64 *)v12, v26 + 15, v26);
            if( v27 == v26 )
              goto LABEL_11;
          }
          _InterlockedExchangeAdd((volatile signed __int32 *)(Value + 12), 0xFFFFFFF1);
        }
      }
      else
      {
        EtwpLockBufferList(LoggerContext, &LockHandle);
        Value = v12->CurrentBuffer.Value & 0xFFFFFFFFFFFFFFF0ui64;
        if( Value )
          _InterlockedIncrement((volatile signed __int32 *)(Value + 12));
        EtwpUnlockBufferList(LoggerContext, &LockHandle);
        LoggerId = v37;
        BufferSize = v36;
      }
LABEL_11:
      if( Value )
      {
        _m_prefetchw((const void *)(Value + 8));
        v16 = *(_DWORD *)(Value + 8);
        if( v16 <= BufferSize )
          break;
      }
    }
LABEL_29:
    LODWORD(v35) = Flags;
    v25 = EtwpSwitchBuffer(LoggerContext, (_WMI_BUFFER_HEADER *)Value, (_EX_FAST_REF *)v12, ProcessorIndex, v35);
    if( (LoggerContext->LoggerMode & 0x4000000) != 0 )
    {
      PerformanceCounter = KeQueryPerformanceCounter(0i64);
      v32 = PerformanceCounter
          - _InterlockedExchange64((volatile __int64 *)&LoggerContext->LastBufferSwitchTime, PerformanceCounter);
      do
      {
        QuadPart = LoggerContext->BufferWriteDuration.QuadPart;
        if( QuadPart )
        {
          RequiredSize = ((QuadPart + v32 + 2 * QuadPart) >> 63) & 3;
          v34 = (QuadPart + v32 + 2 * QuadPart) / 4;
        }
        else
        {
          v34 = v32;
        }
      }
      while( QuadPart != _InterlockedCompareExchange64(
                            (volatile signed __int64 *)&LoggerContext->BufferWriteDuration,
                            v34,
                            QuadPart) );
    }
    if( v25 < 0 )
      goto LABEL_40;
    LoggerId = v37;
    BufferSize = v36;
  }
  while( 1 )
  {
    if( (LoggerContext->Flags & 0x8000000) != 0 )
    {
      if( EtwpGetTimeStampAndQpcDelta((__int64)LoggerContext) )
      {
        LoggerId = v37;
LABEL_62:
        BufferSize = v36;
        goto LABEL_34;
      }
      LoggerId = v37;
      v28 = v11->QpcDelta[v37];
      v40 = 8i64 * v37;
      if( v28 || v16 == 72 )
      {
        v29 = _InterlockedCompareExchange((volatile signed __int32 *)(Value + 8), v16 + 24, v16);
        if( v16 == v29 )
        {
          if( (unsigned __int64)v29 + 24 > v36 )
          {
            *(_DWORD *)(Value + 4) = v29;
            goto LABEL_29;
          }
          RequiredSize = (UINT64)&v11->QpcDelta[v40 / 8];
          v30 = v28 == _InterlockedCompareExchange64((volatile signed __int64 *)RequiredSize, 0i64, v28);
          *(_DWORD *)(v29 + Value + 4) = 5308440;
          v16 = v29;
          *(_QWORD *)(v29 + Value + 8) = 0i64;
          if( v30 )
          {
            *(_QWORD *)(v29 + Value + 16) = 0i64;
            *(_DWORD *)(v29 + Value) = -1072627710;
          }
          else
          {
            *(_DWORD *)(v29 + Value) = -1072627711;
            *(_QWORD *)(v29 + Value + 16) = 0i64;
          }
        }
        else
        {
          v16 = v29;
        }
        goto LABEL_62;
      }
      v18 = 0i64;
      BufferSize = v36;
    }
    else
    {
      GetCpuClock = LoggerContext->GetCpuClock;
      if( GetCpuClock > 3 )
        goto LABEL_70;
      if( (_DWORD)GetCpuClock == 3 )
      {
        v18 = __rdtsc();
      }
      else if( (_DWORD)GetCpuClock )
      {
        v24 = GetCpuClock - 1;
        if( v24 )
        {
          if( v24 != 1 )
LABEL_70:
            __fastfail(0x3Du);
          v39 = 0i64;
          ((void(__fastcall *)(LONGLONG *, UINT64, __int64))off_140C009E0[0])(&v39, RequiredSize, LoggerId);
          v18 = v39;
          LoggerId = v37;
          BufferSize = v36;
        }
        else
        {
          v18 = KeQueryPerformanceCounter(0i64);
          LoggerId = v37;
          BufferSize = v36;
        }
      }
      else
      {
        LODWORD(v18) = RtlGetSystemTimePrecise();
        LoggerId = v37;
        BufferSize = v36;
      }
    }
    TimeStamp->QuadPart = v18;
    v19 = _InterlockedCompareExchange((volatile signed __int32 *)(Value + 8), v10 + v16, v16);
    RequiredSize = v19;
    if( v16 == v19 )
      break;
    v16 = v19;
LABEL_34:
    if( v16 > BufferSize )
      goto LABEL_29;
  }
  if( v19 + v10 > BufferSize )
  {
    *(_DWORD *)(Value + 4) = v19;
    goto LABEL_29;
  }
  if( (LoggerContext->LoggerMode & 0x400) != 0 )
  {
    v20 = *(_QWORD *)(Value + 16);
    for( i = TimeStamp->QuadPart; TimeStamp->QuadPart > v20; i = TimeStamp->QuadPart )
    {
      v22 = v20;
      v20 = _InterlockedCompareExchange64((volatile signed __int64 *)(Value + 16), i, v20);
      if( v22 == v20 )
        break;
    }
  }
  ++v11->EventsLoggedCount[(unsigned int)LoggerId];
  result = (VOID *)(Value + RequiredSize);
  *(_QWORD *)BufferHandle = Value;
  *((_QWORD *)BufferHandle + 1) = v12;
  BufferHandle[4] = RequiredSize;
  return result;
}

Referenced by:

EtwTraceEvent
EtwTraceRaw
EtwpEventWriteFull
EtwpLogContextSwapEvent
EtwpLogKernelEvent
EtwpLogSystemEventUnsafe
EtwpReserveWithPebsIndex
EtwpReserveWithPmcCounters
EtwpTraceMessageVa
EtwpWriteUserEvent