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