PsShutdownSystem

INT64 __fastcall PsShutdownSystem(){
  unsigned int v0; 
  __int64 *ServerSiloGlobals; 
  _EJOB *i; 
  _EJOB *NextSilo; 
  _EJOB *v5; 
  int v6; 
  __int64 v7; 
  _DWORD *NextProcess; 
  UINT64 v9; 
  ULONG_PTR v10; 
  int v11; 
  int v12; 
  int v13; 
  PADAPTER_OBJECT *v14; 
  __int64 v15; 
  ULONG_PTR v16; 
  _EX_FAST_REF **v17; 
  __int64 v18; 
  _EX_FAST_REF *v19; 
  unsigned __int64 Value; 
  _ETHREAD *CurrentThread; 
  struct _DMA_ADAPTER *v22; 
  struct _DMA_ADAPTER *v23; 
  UINT64 v24; 
  int v25[8]; 
  union _LARGE_INTEGER Timeout; 
  PVOID Object[2]; 
  __int64 v28; 
  Timeout.QuadPart = -1000000000i64;
  *(_OWORD *)Object = 0i64;
  v28 = 0i64;
  v0 = 1;
  ServerSiloGlobals = PsGetServerSiloGlobals(0i64);
  if( _InterlockedCompareExchange64(&PspShutdownThread, (signed __int64)KeGetCurrentThread(), 0i64) )
    return 0i64;
  if( PsIsCurrentThreadInServerSilo() )
    NT_ASSERT("PsIsCurrentThreadInServerSilo() == 0");
  for( i = 0i64; ; i = v5 )
  {
    NextSilo = PspGetNextSilo(i, 1u);
    v5 = NextSilo;
    if( !NextSilo )
      break;
    PsTerminateServerSilo(NextSilo, 3221226219i64);
  }
  PsEnumProcesses((__int64(__fastcall *)(unsigned __int64, __int64))PspFreezeProcessWorker, 0i64);
  v6 = 0;
  while( 1 )
  {
    v7 = 0i64;
    NextProcess = (_DWORD *)PsGetNextProcess(0i64);
    if( NextProcess )
    {
      do
      {
        if( (NextProcess[543] & 0x1000) == 0
          && NextProcess != PsIdleProcess
          && NextProcess != (_DWORD *)ServerSiloGlobals[110]
          && !SmIsCompressionProcess(NextProcess) )
        {
          v11 = PsTerminateProcess(v10, 0xC00002EB);
          if( (NextProcess[281] & 4) == 0 && v11 != 290 && (unsigned int)v7 < 3 )
          {
            ObfReferenceObject(NextProcess);
            Object[v7] = NextProcess;
            v7 = (unsigned int)(v7 + 1);
          }
        }
        NextProcess = (_DWORD *)PsGetNextProcess(NextProcess);
      }
      while( NextProcess );
      if( (_DWORD)v7 )
      {
        KeWaitForMultipleObjects((_BYTE *)(unsigned int)v7, Object, WaitAny, Executive, 0, 0, &Timeout, 0i64);
        v13 = v12;
        v14 = (PADAPTER_OBJECT *)Object;
        v15 = (unsigned int)v7;
        do
        {
          HalPutDmaAdapter(*v14++);
          --v15;
        }
        while( v15 );
        if( v13 == 258 )
          break;
      }
    }
    v6 = 0;
LABEL_42:
    if( !(_DWORD)v7 )
      goto LABEL_26;
  }
  if( (unsigned int)++v6 <= 0xA || PsContinueWaiting )
    goto LABEL_42;
  v0 = 0;
LABEL_26:
  if( PopShutdownCleanly )
  {
    v16 = ServerSiloGlobals[110];
    if( v16 )
    {
      PsTerminateProcess(v16, 0xC00002EB);
      PspWaitForUsermodeExit((PEPROCESS)ServerSiloGlobals[110]);
    }
  }
  v17 = (_EX_FAST_REF **)&PspSystemDlls;
  v18 = 6i64;
  do
  {
    v19 = *v17;
    if( *v17 )
    {
      Value = v19[5].Value;
      if( Value )
      {
        MiUnmapViewOfSection((ULONG_PTR)PsInitialSystemProcess, Value, 0, 0);
        v19 = *v17;
      }
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      v22 = (struct _DMA_ADAPTER *)ObFastReplaceObject(v19, 0i64, v9);
      if( v22 )
      {
        --*((_WORD *)CurrentThread + 242);
        _InterlockedOr(v25, 0);
        if( (v19[1].Value & 1) != 0 )
          ExfAcquireReleasePushLockExclusive(&v19[1]);
        KeLeaveCriticalRegionThread((__int64)CurrentThread);
        HalPutDmaAdapter(v22);
      }
    }
    ++v17;
    --v18;
  }
  while( v18 );
  ZwClose(*((HANDLE *)PspSystemPartition + 14));
  *((_QWORD *)PspSystemPartition + 14) = 0i64;
  v23 = (struct _DMA_ADAPTER *)*((_QWORD *)PsInitialSystemProcess + 183);
  if( (unsigned __int64)v23 >= 2 )
  {
    HalPutDmaAdapter(v23);
    *((_QWORD *)PsInitialSystemProcess + 183) = 1i64;
  }
  v24 = qword_140C01AD0;
  qword_140C01AD0 = 0i64;
  dword_140C01AB0 = 0;
  EtwUnregister(v24);
  return v0;
}

Referenced by:

PopGracefulShutdown