EtwpReceiveNotification

NTSTATUS __stdcall EtwpReceiveNotification(VOID *Buffer, UINT64 BufferSize, UINT8 Wow64, UINT64 *ReturnLength){
  NTSTATUS v4; 
  unsigned int v7; 
  _EX_PUSH_LOCK *EtwDataSource; 
  _ETHREAD *CurrentThread; 
  ULONG_PTR v11; 
  _ETW_QUEUE_ENTRY **v12; 
  _ETW_QUEUE_ENTRY *i; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *Blink; 
  _ETWP_NOTIFICATION_HEADER *DataBlock; 
  _ETW_QUEUE_ENTRY *v17; 
  signed __int32 v18; 
  _ETW_QUEUE_ENTRY *v20; 

  v4 = 0;
  v7 = BufferSize;
  EtwDataSource = (_EX_PUSH_LOCK *)KeGetCurrentThread()->ApcState.Process->EtwDataSource;
  if( !EtwDataSource )
    return -1073741811;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.KernelApcDisable;
  v11 = (_DWORD)EtwDataSource + 16;
  ExAcquirePushLockExclusiveEx(EtwDataSource + 2, 0i64);
  v12 = (_ETW_QUEUE_ENTRY **)&EtwDataSource[3];
  for( i = *v12;
        i != (_ETW_QUEUE_ENTRY *)v12 && Wow64 != (HIBYTE(i->RegEntry->Flags) & 1);
        i = (_ETW_QUEUE_ENTRY *)i->ListEntry.Flink )
  {
    ;
  }
  if( i == (_ETW_QUEUE_ENTRY *)v12 )
  {
    ExReleasePushLockEx(v11, 0);
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
    return -2147483622;
  }
  Flink = i->ListEntry.Flink;
  if( (_ETW_QUEUE_ENTRY *)i->ListEntry.Flink->Blink != i )
    goto LABEL_20;
  Blink = i->ListEntry.Blink;
  if( (_ETW_QUEUE_ENTRY *)Blink->Flink != i )
    goto LABEL_20;
  Blink->Flink = Flink;
  Flink->Blink = Blink;
  DataBlock = i->DataBlock;
  if( DataBlock->NotificationSize <= v7 )
    goto LABEL_9;
  v20 = *v12;
  if( (_ETW_QUEUE_ENTRY **)(*v12)->ListEntry.Blink != v12 )
LABEL_20:
    __fastfail(3u);
  i->ListEntry.Flink = &v20->ListEntry;
  v4 = -1073741789;
  i->ListEntry.Blink = (_LIST_ENTRY *)v12;
  v20->ListEntry.Blink = &i->ListEntry;
  *v12 = i;
LABEL_9:
  v17 = *v12;
  *(_DWORD *)ReturnLength = DataBlock->NotificationSize;
  ExReleasePushLockEx(v11, 0);
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
  if( v4 >= 0 )
  {
    v18 = _InterlockedIncrement((volatile signed __int32 *)&DataBlock->20);
    memmove(Buffer, DataBlock, DataBlock->NotificationSize);
    *((_QWORD *)Buffer + 3) = 0i64;
    *((_DWORD *)Buffer + 5) = v18;
    *((_DWORD *)Buffer + 6) = i->RegIndex;
    if( DataBlock->ReplyRequested )
      *((_DWORD *)Buffer + 4) = i->ReplyIndex;
    EtwpUnreferenceDataBlock(DataBlock);
    EtwpReleaseQueueEntry(i, 1ui64);
    if( v17 != (_ETW_QUEUE_ENTRY *)v12 )
      return 261;
  }
  return v4;
}

Referenced by:

NtTraceControl