PspSetCreateProcessNotifyRoutine

UINT64 __stdcall PspSetCreateProcessNotifyRoutine(PVOID NotifyRoutine, UINT64 Flags){
  KSPIN_LOCK v2; 
  int v3; 
  struct EX_RUNDOWN_REF *v5; 
  __int64 v6; 
  _ETHREAD *CurrentThread; 
  __int64 v8; 
  struct EX_RUNDOWN_REF *v9; 
  EX_RUNDOWN_REF *v10; 
  volatile signed __int32 *v11; 
  v2 = (unsigned int)Flags;
  v3 = Flags & 2;
  if( (Flags & 1) != 0 )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)CurrentThread + 242);
    v8 = 0i64;
    while( 1 )
    {
      v9 = ExReferenceCallBackBlock((INT64 *)&PspCreateProcessNotifyRoutine.Ptr + v8);
      v10 = v9;
      if( v9 )
      {
        LODWORD(v2) = v2 & 0xFFFFFFFE;
        if( v9[1].Ptr == NotifyRoutine
          && LODWORD(v9[2].Count) == (_DWORD)v2
          && ExCompareExchangeCallBack((INT64 *)&PspCreateProcessNotifyRoutine.Ptr + v8, 0i64, (INT64)v9) )
        {
          v11 = &PspCreateProcessNotifyRoutineCount;
          if( v3 )
            v11 = &PspCreateProcessNotifyRoutineExCount;
          _InterlockedDecrement(v11);
          ExDereferenceCallBackBlock((INT64 *)&PspCreateProcessNotifyRoutine.Ptr + v8, v10);
          KeLeaveCriticalRegionThread((__int64)CurrentThread);
          ExWaitForRundownProtectionRelease(v10);
          ExFreePoolWithTag(v10, 0);
          return 0i64;
        }
        ExDereferenceCallBackBlock((INT64 *)&PspCreateProcessNotifyRoutine.Ptr + v8, v10);
      }
      v8 = (unsigned int)(v8 + 1);
      if( (unsigned int)v8 >= 0x40 )
      {
        KeLeaveCriticalRegionThread((__int64)CurrentThread);
        return 3221225594i64;
      }
    }
  }
  if( !(unsigned int)MmVerifyCallbackFunctionCheckFlags(NotifyRoutine) )
    return 3221225506i64;
  v5 = ExAllocateCallBack((KSPIN_LOCK)NotifyRoutine, v2);
  if( !v5 )
    return 3221225626i64;
  v6 = 0i64;
  while( !ExCompareExchangeCallBack((INT64 *)&PspCreateProcessNotifyRoutine.Ptr + v6, v5, 0i64) )
  {
    v6 = (unsigned int)(v6 + 1);
    if( (unsigned int)v6 >= 0x40 )
    {
      ExFreePoolWithTag(v5, 0);
      return 3221225485i64;
    }
  }
  if( v3 )
  {
    _InterlockedIncrement(&PspCreateProcessNotifyRoutineExCount);
    if( (PspNotifyEnableMask & 4) == 0 )
      _interlockedbittestandset(&PspNotifyEnableMask, 2u);
  }
  else
  {
    _InterlockedIncrement(&PspCreateProcessNotifyRoutineCount);
    if( (PspNotifyEnableMask & 2) == 0 )
      _interlockedbittestandset(&PspNotifyEnableMask, 1u);
  }
  return 0i64;
}

Referenced by:

PsSetCreateProcessNotifyRoutine
PsSetCreateProcessNotifyRoutineEx
PsSetCreateProcessNotifyRoutineEx2