KiTimerWaitTest

_KDPC *__stdcall KiTimerWaitTest(_KPRCB *Prcb, _KTIMER *Timer, _ULARGE_INTEGER *SystemTime){
  char v3; 
  unsigned __int16 v4; 
  __int64 Period; 
  char v7; 
  _ULARGE_INTEGER *v9; 
  unsigned __int64 v10; 
  UINT8 v11; 
  __int64 v12; 
  unsigned __int64 v13; 
  _KTIMER *v14; 
  _KTIMER *v15; 
  UINT64 v16; 
  _KWAIT_BLOCK *Flink; 
  _KWAIT_BLOCK *v18; 
  _KWAIT_BLOCK *v20; 
  unsigned __int8 WaitType; 
  INT64 WaitKey; 
  _KWAIT_BLOCK *v23; 
  _KWAIT_BLOCK *v24; 
  _KWAIT_BLOCK **Blink; 
  unsigned __int8 v26; 
  bool v27; 
  _QWORD *v28; 
  _ETHREAD *v29; 
  char v30; 
  bool v31; 
  _KTIMER *v32; 
  int v33; 
  _KWAIT_BLOCK **QuantumTarget; 
  _QWORD *v35; 
  _ETHREAD *v36; 
  int v37; 
  _ETHREAD **v38; 
  char v39; 
  unsigned int PeriodicBias; 
  _QWORD *v41; 
  _KPRCB *Prcba; 
  _KPRCB *Prcbb; 
  __int64 v44; 
  _ETHREAD *CurrentThread; 
  __int128 v46; 
  __int64 v47; 
  _ETHREAD *Object; 
  _ETHREAD *Objecta; 
  _KWAIT_BLOCK *Entry; 
  INT64 Entrya; 

  v3 = Timer->gap0[0];
  v4 = 0;
  v47 = 0i64;
  Period = (int)Timer->Period;
  v7 = v3 & 0x7F;
  v44 = 0i64;
  v9 = SystemTime;
  v10 = KiWaitAlways ^ _byteswap_uint64((unsigned __int64)Timer ^ __ROL8__(
                                                                    (__int64)Timer->Dpc ^ KiWaitNever,
                                                                    KiWaitNever));
  v11 = -1;
  v46 = 0i64;
  if( (_DWORD)Period )
  {
    v12 = -10000 * Period;
    v11 = 0;
    if( Prcb->DpcRoutineActive )
    {
      if( ++Prcb->PeriodicCount >= 0xBB8 )
      {
        PeriodicBias = Prcb->PeriodicBias;
        Prcb->PeriodicCount = 0;
        if( PeriodicBias < 0x5F5E100 )
          Prcb->PeriodicBias = KeTimeIncrement + PeriodicBias;
      }
      v12 -= Prcb->PeriodicBias;
    }
    if( (signed __int64)(v12 + *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart - Timer->DueTime.QuadPart) >= 0 )
      Timer->DueTime.QuadPart = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
    v13 = 0i64;
    LODWORD(v46) = *(_DWORD *)Timer->gap0;
    if( BYTE1(v46) >= 4u )
      v13 = (unsigned __int64)(BYTE1(v46) & 0xFC) << 16;
    if( (KiVelocityFlags & 0x2000) != 0 )
    {
      v14 = *(_KTIMER **)&Timer->gap0[8];
      Timer->TimerType = 1;
      v15 = (_KTIMER *)&Timer->gap0[8];
      if( v14 == (_KTIMER *)&Timer->gap0[8] )
        goto LABEL_9;
      while( 1 )
      {
        v31 = v14->gap0[16] <= 1u;
        v32 = v14;
        v14 = *(_KTIMER **)v14->gap0;
        if( v31 )
        {
          if( PsTimerResolutionActive(*(_QWORD *)(v32->DueTime.QuadPart + 544)) )
            break;
        }
        if( v14 == v15 )
          goto LABEL_9;
      }
    }
    Timer->TimerType = v4;
LABEL_9:
    BYTE1(v46) &= ~1u;
    BYTE3(v46) = 64;
    do
    {
      Timer->DueTime.QuadPart -= v12;
      BYTE2(v46) = (v13 + Timer->DueTime.QuadPart) >> 18;
      v16 = BYTE2(v46);
      *(_DWORD *)Timer->gap0 = v46;
    }
    while( !KiInsertTimerTable(Prcb, Timer, (_KDPC *)v10, v16, 0i64) );
    v9 = SystemTime;
  }
  Flink = *(_KWAIT_BLOCK **)&Timer->gap0[8];
  v18 = (_KWAIT_BLOCK *)&Timer->gap0[8];
  *(_DWORD *)&Timer->gap0[4] = 1;
  if( v7 == 8 )
  {
    if( Flink == v18 )
    {
LABEL_14:
      *(_QWORD *)&Timer->gap0[16] = &Timer->gap0[8];
      v18->WaitListEntry.Flink = &v18->WaitListEntry;
      goto LABEL_15;
    }
    while( 1 )
    {
      v20 = Flink;
      Flink = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
      WaitType = v20->WaitType;
      if( WaitType == 1 )
      {
        WaitKey = v20->WaitKey;
      }
      else
      {
        if( WaitType == 2 )
        {
          v20->BlockState = 5;
          Object = v20->Thread;
          Entrya = (INT64)&Object->Tcb.gap0[8];
          v20->WaitListEntry.Flink = 0i64;
          KeGetCurrentIrql();
          __writecr8(2ui64);
          Prcba = KeGetCurrentPrcb();
          CurrentThread = Prcba->CurrentThread;
          KiAcquireKobjectLockSafe(Object);
          v28 = (_QWORD *)Entrya;
          v29 = Object;
          if( (_QWORD *)*v28 == v28
            || LODWORD(Object->Tcb.InitialStack) >= HIDWORD(Object->Tcb.InitialStack)
            || (_ETHREAD *)CurrentThread->Tcb.Queue == Object && CurrentThread->Tcb.WaitReason == 15 )
          {
LABEL_52:
            v33 = *(_DWORD *)&v29->Tcb.gap0[4];
            *(_DWORD *)&v29->Tcb.gap0[4] = v33 + 1;
            QuantumTarget = (_KWAIT_BLOCK **)v29->Tcb.QuantumTarget;
            if( *QuantumTarget != (_KWAIT_BLOCK *)&v29->Tcb.SListFaultAddress )
              goto LABEL_32;
            v20->WaitListEntry.Flink = (_LIST_ENTRY *)&v29->Tcb.SListFaultAddress;
            v20->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
            *QuantumTarget = v20;
            v29->Tcb.QuantumTarget = (unsigned __int64)v20;
            if( !v33 && (_QWORD *)*v28 != v28 )
            {
              KiWakeOtherQueueWaiters(Prcba, (_KQUEUE *)v29);
              v29 = Object;
            }
          }
          else
          {
            KiWakeQueueWaiter(Prcba, (_KQUEUE *)Object, (INT64)v20);
            v29 = Object;
            if( !v30 )
            {
              v28 = &Object->Tcb.gap0[8];
              goto LABEL_52;
            }
          }
          _InterlockedAnd((volatile signed __int32 *)v29, 0xFFFFFF7F);
          goto LABEL_26;
        }
        WaitKey = 256i64;
      }
      KiTryUnwaitThread(Prcb, v20, WaitKey, 0i64);
LABEL_26:
      if( Flink == v18 )
        goto LABEL_14;
    }
  }
  if( Flink != v18 )
  {
    while( 1 )
    {
      v23 = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
      v24 = Flink;
      Entry = Flink;
      Flink = v23;
      Blink = (_KWAIT_BLOCK **)Entry->WaitListEntry.Blink;
      if( (_KWAIT_BLOCK *)v23->WaitListEntry.Blink != Entry || *Blink != v24 )
LABEL_32:
        __fastfail(3u);
      *Blink = v23;
      v23->WaitListEntry.Blink = (_LIST_ENTRY *)Blink;
      v26 = v24->WaitType;
      if( v26 != 1 )
        break;
      if( KiTryUnwaitThread(Prcb, v24, v24->WaitKey, 0i64) )
      {
        v27 = (*(_DWORD *)&Timer->gap0[4])-- == 1;
        if( v27 )
          goto LABEL_15;
      }
LABEL_39:
      if( Flink == v18 )
        goto LABEL_15;
    }
    if( v26 != 2 )
    {
      KiTryUnwaitThread(Prcb, v24, 256i64, 0i64);
      goto LABEL_39;
    }
    v24->BlockState = 5;
    Objecta = v24->Thread;
    v41 = &Objecta->Tcb.gap0[8];
    v24->WaitListEntry.Flink = 0i64;
    KeGetCurrentIrql();
    __writecr8(2ui64);
    Prcbb = KeGetCurrentPrcb();
    CurrentThread = Prcbb->CurrentThread;
    KiAcquireKobjectLockSafe(Objecta);
    v35 = v41;
    v36 = Objecta;
    if( (_QWORD *)*v35 != v35
      && LODWORD(Objecta->Tcb.InitialStack) < HIDWORD(Objecta->Tcb.InitialStack)
      && ((_ETHREAD *)CurrentThread->Tcb.Queue != Objecta || CurrentThread->Tcb.WaitReason != 15) )
    {
      KiWakeQueueWaiter(Prcbb, (_KQUEUE *)Objecta, (INT64)Entry);
      v36 = Objecta;
      if( v39 )
        goto LABEL_67;
      v35 = &Objecta->Tcb.gap0[8];
    }
    v37 = *(_DWORD *)&v36->Tcb.gap0[4];
    *(_DWORD *)&v36->Tcb.gap0[4] = v37 + 1;
    v38 = (_ETHREAD **)v36->Tcb.QuantumTarget;
    if( *v38 != (_ETHREAD *)&v36->Tcb.SListFaultAddress )
      goto LABEL_32;
    Entry->WaitListEntry.Flink = (_LIST_ENTRY *)&v36->Tcb.SListFaultAddress;
    Entry->WaitListEntry.Blink = (_LIST_ENTRY *)v38;
    *v38 = (_ETHREAD *)Entry;
    v36->Tcb.QuantumTarget = (unsigned __int64)Entry;
    if( !v37 && (_QWORD *)*v35 != v35 )
    {
      KiWakeOtherQueueWaiters(Prcbb, (_KQUEUE *)v36);
      v36 = Objecta;
    }
LABEL_67:
    _InterlockedAnd((volatile signed __int32 *)v36, 0xFFFFFF7F);
    v27 = (*(_DWORD *)&Timer->gap0[4])-- == 1;
    if( v27 )
      goto LABEL_15;
    goto LABEL_39;
  }
LABEL_15:
  if( v10 )
  {
    if( v9 )
    {
      if( (!KiSerializeTimerExpiration || *(_WORD *)(v10 + 2) < 0x500u)
        && (*(_BYTE *)v10 != 26 || !Prcb->ThreadDpcEnable) )
      {
        Prcb->DpcData[0].ActiveDpc = (_KDPC *volatile)v10;
        if( (Prcb->GroupSetMember & *(_QWORD *)(v10 + 16)) == 0 )
          _interlockedbittestandset64((volatile signed __int32 *)(v10 + 16), Prcb->GroupIndex);
        goto LABEL_21;
      }
    }
    else
    {
      v9 = (_ULARGE_INTEGER *)&v44;
      v44 = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
    }
    KiInsertQueueDpc((_KDPC *)v10, (VOID *)v9->LowPart, (VOID *)v9->HighPart, Timer, v11);
    return 0i64;
  }
LABEL_21:
  _InterlockedAnd((volatile signed __int32 *)Timer, ~((v11 << 24) | 0x80));
  return(_KDPC *)v10;
}

Referenced by:

ExpSetTimerObject
KeSetTimerEx
KiAdjustTimerDueTimes
KiCommitThreadWait
KiProcessExpiredTimerList
KiResumeThread
KiSetTimerEx