PsShutdownSystem

UINT64 __stdcall PsShutdownSystem(){
  unsigned int v0; 
  _ESERVERSILO_GLOBALS *ServerSiloGlobals; 
  _EJOB *i; 
  _EJOB *NextSilo; 
  _EPROCESS *v5; 
  VOID *v6; 
  int v7; 
  __int64 v8; 
  _EPROCESS *NextProcess; 
  UINT64 v10; 
  ULONG_PTR v11; 
  NTSTATUS v12; 
  NTSTATUS v13; 
  VOID **v14; 
  __int64 v15; 
  _EPROCESS *ExpDefaultErrorPortProcess; 
  _EX_FAST_REF **v17; 
  __int64 v18; 
  _EX_FAST_REF *v19; 
  VOID *v20; 
  _ETHREAD *CurrentThread; 
  _ADAPTER_OBJECT *v22; 
  _ADAPTER_OBJECT *SecurityPort; 
  UINT64 v24; 
  int v25[8]; 
  VOID *WaitMode; 
  _LARGE_INTEGER Timeout; 
  VOID *Object[2]; 
  __int64 v29; 

  Timeout.QuadPart = -1000000000i64;
  *(_OWORD *)Object = 0i64;
  v29 = 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 = NextSilo )
  {
    NextSilo = PspGetNextSilo(i, 1u);
    if( !NextSilo )
      break;
    PsTerminateServerSilo();
  }
  PsEnumProcesses((INT64)PspFreezeProcessWorker, 0i64, v5, v6, WaitMode);
  v7 = 0;
  while( 1 )
  {
    v8 = 0i64;
    NextProcess = (_EPROCESS *)PsGetNextProcess(0i64);
    if( NextProcess )
    {
      do
      {
        if( (NextProcess->Flags3 & 0x1000) == 0
          && NextProcess != *(_EPROCESS **)&PsIdleProcess
          && NextProcess != ServerSiloGlobals->ExpDefaultErrorPortProcess
          && !(unsigned int)SmIsCompressionProcess(NextProcess) )
        {
          v12 = PsTerminateProcess(v11, 0xC00002EBui64);
          if( (NextProcess->Flags & 4) == 0 && v12 != 290 && (unsigned int)v8 < 3 )
          {
            ObfReferenceObject(NextProcess);
            Object[v8] = NextProcess;
            v8 = (unsigned int)(v8 + 1);
          }
        }
        NextProcess = (_EPROCESS *)PsGetNextProcess(NextProcess);
      }
      while( NextProcess );
      if( (_DWORD)v8 )
      {
        v13 = KeWaitForMultipleObjects((unsigned int)v8, Object, WaitAny, Executive, 0, 0, &Timeout, 0i64);
        v14 = Object;
        v15 = (unsigned int)v8;
        do
        {
          HalPutDmaAdapter((PADAPTER_OBJECT)*v14++);
          --v15;
        }
        while( v15 );
        if( v13 == 258 )
          break;
      }
    }
    v7 = 0;
LABEL_42:
    if( !(_DWORD)v8 )
      goto LABEL_26;
  }
  if( (unsigned int)++v7 <= 0xA || PsContinueWaiting )
    goto LABEL_42;
  v0 = 0;
LABEL_26:
  if( *(&stru_140C23628 + 584) )
  {
    ExpDefaultErrorPortProcess = ServerSiloGlobals->ExpDefaultErrorPortProcess;
    if( ExpDefaultErrorPortProcess )
    {
      PsTerminateProcess((ULONG_PTR)ExpDefaultErrorPortProcess, 0xC00002EBui64);
      PspWaitForUsermodeExit(ServerSiloGlobals->ExpDefaultErrorPortProcess);
    }
  }
  v17 = &PspSystemDlls;
  v18 = 6i64;
  do
  {
    v19 = *v17;
    if( *v17 )
    {
      v20 = v19[5].Object;
      if( v20 )
      {
        MiUnmapViewOfSection(PsInitialSystemProcess, v20, 0i64);
        v19 = *v17;
      }
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      v22 = (_ADAPTER_OBJECT *)ObFastReplaceObject(v19, 0i64, v10);
      if( v22 )
      {
        --CurrentThread->Tcb.KernelApcDisable;
        _InterlockedOr(v25, 0);
        if( (v19[1].Value & 1) != 0 )
          ExfAcquireReleasePushLockExclusive((_EX_PUSH_LOCK *)&v19[1]);
        KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
        HalPutDmaAdapter(v22);
      }
    }
    ++v17;
    --v18;
  }
  while( v18 );
  ZwClose(*(_QWORD *)(PspSystemPartition + 112));
  *(_QWORD *)(PspSystemPartition + 112) = 0i64;
  SecurityPort = (_ADAPTER_OBJECT *)PsInitialSystemProcess->SecurityPort;
  if( (unsigned __int64)SecurityPort >= 2 )
  {
    HalPutDmaAdapter(SecurityPort);
    PsInitialSystemProcess->SecurityPort = (void *)1;
  }
  v24 = *(&stru_140C00F40 + 370);
  *(&stru_140C00F40 + 370) = 0i64;
  *(&stru_140C00F40 + 732) = 0;
  EtwUnregister(v24);
  return v0;
}

Referenced by:

PopGracefulShutdown