PfSnEndTrace

NTSTATUS __stdcall PfSnEndTrace(PFSN_TRACE_HEADER *Trace){
  char PreviousMode; 
  PFSN_TRACE_HEADER v3; 
  PFSN_TRACE_HEADER v4; 
  __int64 v5; 
  PFSN_TRACE_HEADER v6; 
  int v7; 
  _QWORD *v8; 
  _QWORD *v9; 
  unsigned int v10; 
  PVOID v12; 
  __int64 v13; 
  __int64 v14; 
  __int16 v15; 
  PVOID P; 
  _EVENT_DATA_DESCRIPTOR UserData; 
  PFSN_TRACE_HEADER *v18; 
  int v19; 
  int v20; 
  PFSN_TRACE_HEADER *v21; 
  __int64 v22; 
  PFSN_TRACE_HEADER *v23; 
  __int64 v24; 
  PFSN_TRACE_HEADER *v25; 
  __int64 v26; 

  P = 0i64;
  PreviousMode = KeGetCurrentThread()->PreviousMode;
  KeGetCurrentThread()->PreviousMode = 0;
  PfSnDeactivateTrace(Trace);
  if( Trace && qword_140C50288 && EtwEventEnabled(qword_140C50288, &PfSnEvt_EndTrace_Info) )
  {
    v14 = -1i64;
    do
      ++v14;
    while( *((_WORD *)Trace + v14 + 12) );
    v15 = v14;
    UserData.Ptr = (unsigned __int64)&v15;
    v19 = 2 * (unsigned __int16)v14;
    v18 = Trace + 6;
    v21 = Trace + 21;
    v23 = Trace + 22;
    v25 = Trace + 100;
    *(_QWORD *)&UserData.Size = 2i64;
    v20 = 0;
    v22 = 4i64;
    v24 = 4i64;
    v26 = 4i64;
    EtwWrite(qword_140C50288, &PfSnEvt_EndTrace_Info, 0, 5u, &UserData);
  }
  v3 = Trace[81];
  v4 = Trace[83];
  if( v3 > v4 )
  {
    Trace[81] = v4;
    v3 = v4;
  }
  v5 = Trace[82];
  if( (int)v5 >= dword_140C4FFF4 )
  {
    if( (int)v5 > 10 )
    {
      Trace[82] = 10;
      LODWORD(v5) = 10;
    }
    if( v3 != v4 )
      Trace[(int)v5 + 70] += v4 - v3;
  }
  else
  {
    Trace[v5 + 71] = v4 - v3;
    v6 = Trace[83];
    ++Trace[82];
    Trace[81] = v6;
  }
  if( Trace[22] != 1 || Trace[100] == 8 )
    v7 = PfSnBuildDumpFromTrace(&P, Trace);
  else
    v7 = -2147483614;
  v8 = P;
  *((_QWORD *)Trace + 56) = P;
  Trace[114] = v7;
  PfSnCleanupTrace(Trace);
  ExFreePoolWithTag(Trace, 0);
  if( v7 >= 0 )
  {
    PfFbBufferListFlushStandby((_SLIST_ENTRY *)&stru_140C4DB30 + 491);
    ExAcquireFastMutex(&FastMutex);
    if( dword_140C501E4 == 1 )
    {
      KeReleaseGuardedMutex(&FastMutex);
      ExFreePoolWithTag(v8, 0);
    }
    else
    {
      v9 = qword_140C501A0;
      if( *(PVOID **)qword_140C501A0 != &qword_140C50198 )
LABEL_29:
        __fastfail(3u);
      v8[1] = qword_140C501A0;
      *v8 = &qword_140C50198;
      *v9 = v8;
      v10 = dword_140C501E0 + 1;
      qword_140C501A0 = v8;
      while( 1 )
      {
        dword_140C501E0 = v10;
        if( v10 <= dword_140C4FE8C )
          break;
        v12 = qword_140C50198;
        if( qword_140C50198 == &qword_140C50198 )
          break;
        if( *((PVOID **)qword_140C50198 + 1) != &qword_140C50198 )
          goto LABEL_29;
        v13 = *(_QWORD *)qword_140C50198;
        if( *(PVOID *)(*(_QWORD *)qword_140C50198 + 8i64) != qword_140C50198 )
          goto LABEL_29;
        qword_140C50198 = *(PVOID *)qword_140C50198;
        *(_QWORD *)(v13 + 8) = &qword_140C50198;
        ExFreePoolWithTag(v12, 0);
        v10 = dword_140C501E0 - 1;
      }
      KeReleaseGuardedMutex(&FastMutex);
      if( qword_140C501E8 )
        KeSetEvent(qword_140C501E8, 0, 0);
      v7 = 0;
    }
  }
  KeGetCurrentThread()->PreviousMode = PreviousMode;
  return v7;
}

Referenced by:

PfSnEndTraceWorkerThreadRoutine