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