PopInvokeSystemStateHandler

NTSTATUS __stdcall PopInvokeSystemStateHandler(POWER_STATE_HANDLER_TYPE Type, POP_HIBER_CONTEXT *HiberContext){
  __int64 v3; 
  unsigned __int8 CurrentIrql; 
  signed int Next; 
  POP_HIBER_CONTEXT *v6; 
  NTSTATUS(__stdcall *v7)(POP_HIBER_CONTEXT *); 
  POP_HIBER_CONTEXT *v8; 
  __int64 *v9; 
  __int64 v10; 
  UINT64 PerformanceCounter; 
  UINT64 v12; 
  VOID *v13; 
  UINT64 v14; 
  char v15; 
  char v16; 
  __int64 v17; 
  char v18; 
  __int64 v20; 
  unsigned int i; 
  int v22; 
  bool v23; 
  UINT64 v24; 
  _GROUP_AFFINITY Affinity; 
  UINT64 v26; 
  _KDPC Dpc; 
  __int64 DeferredContext[10]; 
  __int64 *v29; 
  int v30; 
  int v31; 
  __int64 v32[2]; 
  __int64 v33[2]; 
  _SLIST_ENTRY LocalContext[9]; 
  __int128 v35; 
  __int64 v36; 

  v3 = Type;
  Affinity = 0i64;
  memset(&Dpc, 0i64, sizeof(Dpc));
  v24 = 0i64;
  CurrentIrql = 0;
  Next = -1073741823;
  memset(DeferredContext, 0i64, sizeof(DeferredContext));
  LODWORD(DeferredContext[5]) = v3;
  v36 = 0i64;
  DeferredContext[0] = (__int64)&v35;
  DeferredContext[4] = (__int64)&PopPowerStateNotifyHandler;
  v35 = 0i64;
  if( (_DWORD)v3 != 7 )
  {
    DeferredContext[0] = (__int64)&stru_140C23628 + 24 * v3 + 1880;
    if( !*(_QWORD *)(DeferredContext[0] + 8) )
      return -1073741632;
  }
  LODWORD(DeferredContext[6]) = KeNumberProcessors_0;
  HIDWORD(DeferredContext[7]) = KeNumberProcessors_0;
  LODWORD(DeferredContext[7]) = 1;
  if( (unsigned int)(v3 - 4) > 1 && PopCheckpointSystemSleepEnabled )
  {
    v20 = *(unsigned int *)(DeferredContext[0] + 16);
    LODWORD(v20) = v20 | 0x40000;
    *(_QWORD *)(DeferredContext[0] + 16) = v20;
  }
  if( ((_DWORD)v3 == 3 || (_DWORD)v3 == 6) && HiberContext )
  {
    v6 = HiberContext;
    DeferredContext[2] = (__int64)HiberContext;
    v7 = PopSaveHiberContextWrapper;
    DeferredContext[3] = (__int64)HiberContext;
    DeferredContext[1] = (__int64)PopSaveHiberContextWrapper;
    v8 = HiberContext;
  }
  else
  {
    v6 = (POP_HIBER_CONTEXT *)DeferredContext[3];
    v8 = (POP_HIBER_CONTEXT *)DeferredContext[2];
    v7 = (NTSTATUS(__stdcall *)(POP_HIBER_CONTEXT *))DeferredContext[1];
  }
  memset(LocalContext, 0i64, sizeof(LocalContext));
  if( HiberContext )
  {
    *(_QWORD *)&qword_140C503A0 = DeferredContext[0];
    qword_140C503C0 = DeferredContext[4];
    dword_140C503C8 = DeferredContext[5];
    byte_140C503CC = BYTE4(DeferredContext[5]);
    dword_140C503D0 = DeferredContext[6];
    qword_140C503A8 = (__int64)v7;
    v9 = (__int64 *)&qword_140C503A0;
    qword_140C503B0 = (__int64)v8;
    qword_140C503B8 = (__int64)v6;
    qword_140C503D8 = DeferredContext[7];
    RtlpInterlockedPushEntrySList(&stru_140C503E0, &LocalContext[8]);
  }
  else
  {
    Affinity.Reserved[1] = 0;
    *(_DWORD *)&Affinity.Group = (unsigned __int16)((unsigned int)KiProcessorIndexToNumberMappingTable[0] >> 6);
    Affinity.Reserved[2] = 0;
    Affinity.Mask = 1i64 << (KiProcessorIndexToNumberMappingTable[0] & 0x3F);
    KeSetSystemGroupAffinityThread(&Affinity, 0i64);
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    KeInitializeDpc(&Dpc, PopInvokeStateHandlerTargetProcessor, DeferredContext);
    Dpc.Importance = 2;
    for( i = 0; i < (unsigned int)KeNumberProcessors_0; ++i )
    {
      if( i != KeGetCurrentPrcb()->Number )
      {
        v22 = HIDWORD(DeferredContext[6]);
        if( !Dpc.DpcData )
          Dpc.Number = i + 1280;
        KeInsertQueueDpc((UINT64)&Dpc, 0i64, 0i64);
        while( v22 == HIDWORD(DeferredContext[6]) )
          _mm_pause();
      }
    }
    v9 = DeferredContext;
  }
  PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 2ui64);
  PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 3ui64);
  if( SystemState == PowerSystemSleeping3 )
  {
    PerformanceCounter = 0i64;
    v10 = 1000000i64 * KeGetCurrentPrcb()->MHz;
  }
  else
  {
    v10 = PopQpcFrequency;
    PerformanceCounter = KeQueryPerformanceCounter(0i64);
  }
  if( (xmmword_140CFB490 & 0x8000) != 0 )
  {
    v31 = 0;
    v29 = v33;
    v33[0] = PerformanceCounter;
    v33[1] = v10;
    v30 = 16;
    EtwTraceKernelEvent((__int64)&v29, 1u, 0x80008000, 0x1230u, 0x401802u);
  }
  PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 4ui64);
  if( HiberContext )
  {
    byte_140C50450 = 0;
    if( VfIsVerifierEnabled() )
      VfNotifyOfHibernate(1u);
  }
  PoAllProcIntrDisabled = 1;
  PopCheckpointSystemSleep(PopSleepCheckpointInterruptsDisabledBegin);
  if( SLODWORD(LocalContext[7].Next) >= 0 )
  {
    *((_BYTE *)v9 + 44) = 1;
    PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xCui64);
    if( (_DWORD)v3 != 3 && (_DWORD)v3 != 6 )
      off_140C008C8[0]();
    if( HiberContext )
    {
      PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 5ui64);
      if( (*(&stru_140C23628 + 1166) & 0x100) == 0 )
        MiUpdateUserMappings(v12);
      PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xAui64);
    }
    PopCheckpointSystemSleep(PopSleepCheckpointInvokeHandlerBefore);
    PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 6ui64);
    PopCheckpointSystemSleep(PopSleepCheckpointInvokeHandlerAfter);
    Next = (signed int)LocalContext[7].Next;
    KeRebaselineInterruptTime();
    off_140C008B8[0]();
    if( HiberContext && Next == 1073742484 )
      PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 7ui64);
    PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 8ui64);
    if( HiberContext )
    {
      if( Next == 1073742484 )
      {
        PopCheckpointSystemSleep(PopSleepCheckpointReadHiberfileBefore);
        PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 9ui64);
        PopCheckpointSystemSleep(PopSleepCheckpointReadHiberfileAfter);
      }
      MmInvalidateDumpAddresses(Va, 0x13ui64);
      v13 = (VOID *)*((_QWORD *)HiberContext + 38);
      if( v13 )
        MmInvalidateDumpAddresses(v13, (unsigned int)(16 * HiberContext[64]));
      PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xAui64);
      if( (*(&stru_140C23628 + 1166) & 0x100) == 0 )
      {
        MiUpdateUserMappings(v14);
        MiConvertHiberPhasePages(0i64);
      }
      *((_BYTE *)HiberContext + 3) = 0;
      PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xBui64);
    }
    v15 = dword_140CED0C0;
    if( (dword_140CED0C0 & 1) != 0 && (_BYTE)KdDebuggerEnabled )
      DbgBreakPointWithStatus(Next);
    if( (v15 & 2) != 0 )
      KeBugCheckEx(0xA0u, (PVOID)0xA, 0i64, 0i64, 0i64);
    PopNoMoreInput = 0;
    if( Next >= 0 )
    {
      ++PoPowerSequence;
      *(&stru_140C23628 + 466) = 0;
      PopPendingUserPresenceDuringSystemSleep = 0;
      PopPendingUserPresenceMonitorOnReason = MonitorRequestReasonUnknown;
      LODWORD(AccumulatedIdleTime) = 1;
      if( PoResumeFromHibernate )
      {
        _InterlockedOr(&PopPendingUserPresenceDuringSystemSleep, 1u);
        _InterlockedOr((volatile signed __int32 *)&PopPendingUserPresenceMonitorOnReason, 0x19u);
      }
    }
    *((_BYTE *)v9 + 44) = 0;
    PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xCui64);
  }
  if( HiberContext )
  {
    if( Next == -1073741632 )
    {
      if( (*(&stru_140C23628 + 1164) & 0x1000) == 0 )
      {
        while( 1 )
          ;
      }
      *(_BYTE *)HiberContext = 1;
    }
    else
    {
      PoHiberInProgress = 0;
      HiberContext[47] = Next;
      if( !*(_BYTE *)HiberContext )
      {
        if( VfIsVerifierEnabled() )
          VfNotifyOfHibernate(0);
        if( (_UNKNOWN *)*(&stru_140C00F40 + 892) == (_UNKNOWN *)((char *)&stru_140C00F40 + 7136) )
          byte_140C50450 = 1;
        HiberContext[47] = 1073742484;
        goto LABEL_49;
      }
    }
    v23 = *(&stru_140C23628 + 251) == 0i64;
    *v9 = (__int64)&stru_140C23628 + 2000;
    v9[3] = 0i64;
    if( !v23 )
      PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 6ui64);
    HalReturnToFirmware(HalRebootRoutine);
  }
LABEL_49:
  KeRebaselineInterruptTime();
  KeRebaselineSystemTime();
  PopCheckpointSystemSleep(PopSleepCheckpointInterruptsDisabledEnd);
  PoAllProcIntrDisabled = 0;
  PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xDui64);
  if( Next >= 0 )
  {
    if( SystemState != PowerSystemSleeping3 || PoResumeFromHibernate )
    {
      v16 = 0;
      v24 = KeQueryPerformanceCounter(0i64);
      ((void(__fastcall *)(char *, char *))off_140C006A0[0])(
        (char *)&stru_140C23628 + 640,
        (char *)&stru_140C23628 + 648);
    }
    else
    {
      v16 = 1;
      if( !((unsigned __int8(__fastcall *)(UINT64 *, _QWORD))off_140C006A0[0])(&v24, 0i64) )
        v24 = 0i64;
    }
    if( (xmmword_140CFB490 & 0x8000) != 0 )
    {
      v26 = v24;
      v32[1] = 8i64;
      v32[0] = (__int64)&v26;
      EtwTraceKernelEvent((__int64)v32, 1u, 0x80008000, 0x1231u, 0x401802u);
    }
    if( v16 )
    {
      v24 = v24 / (1000 * (unsigned __int64)KeGetCurrentPrcb()->MHz) * (PopQpcFrequency / 0x3E8);
      *(&stru_140C23628 + 44) = v24 - PerformanceCounter;
    }
  }
  PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xEui64);
  PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0xFui64);
  PopIssueNextState((_POP_SYS_CONTEXT *)v9, (_POP_PROC_LOCAL_CONTEXT *)LocalContext, 0x10ui64);
  if( SLODWORD(LocalContext[7].Next) >= 0 )
  {
    v17 = *v9;
    LODWORD(LocalContext[7].Next) = 0;
    v18 = *(_BYTE *)(v17 + 5);
    if( v18 != -1 )
      *(_BYTE *)(v17 + 5) = v18 + 1;
  }
  if( HiberContext )
  {
    if( !byte_140C23481 && Next == 1073742484 )
    {
      if( byte_140C50390 )
        BgLibraryInitialize(qword_140C50388, 0i64);
    }
  }
  else
  {
    __writecr8(CurrentIrql);
  }
  return(NTSTATUS)LocalContext[7].Next;
}

Referenced by:

PopEndMirroring
PopShutdownSystem
PopTransitionToSleep