KiTimerWaitTest

VOID __fastcall KiTimerWaitTest(_KPRCB *Prcb, _KTIMER *Timer, _ULARGE_INTEGER *SystemTime){
  char v3; 
  __int16 v4; 
  __int64 v5; 
  char v7; 
  _ULARGE_INTEGER *v9; 
  unsigned __int64 v10; 
  UINT8 v11; 
  __int64 v12; 
  unsigned __int64 v13; 
  char *v14; 
  char *v15; 
  UINT64 v16; 
  _KWAIT_BLOCK *Flink; 
  _KWAIT_BLOCK *v18; 
  _KWAIT_BLOCK *v19; 
  unsigned __int8 WaitType; 
  INT64 WaitKey; 
  _KWAIT_BLOCK *v22; 
  _KWAIT_BLOCK *v23; 
  _KWAIT_BLOCK **v24; 
  unsigned __int8 v25; 
  bool v26; 
  _QWORD *p_Flink; 
  _KQUEUE *v28; 
  UINT8 v29; 
  bool v30; 
  char *v31; 
  int SignalState; 
  _LIST_ENTRY *Blink; 
  _LIST_ENTRY *v34; 
  _KQUEUE *v35; 
  int v36; 
  _LIST_ENTRY *v37; 
  UINT8 v38; 
  unsigned int v39; 
  _LIST_ENTRY *p_WaitListHead; 
  _KPRCB *Prcba; 
  _KPRCB *Prcbb; 
  __int64 v43; 
  __int64 v44; 
  __int128 v45; 
  __int64 v46; 
  _KQUEUE *Object; 
  _KQUEUE *Objecta; 
  _LIST_ENTRY *Entry; 
  INT64 Entrya; 
  v3 = *(_BYTE *)Timer;
  v4 = 0;
  v46 = 0i64;
  v5 = *((int *)Timer + 15);
  v7 = v3 & 0x7F;
  v43 = 0i64;
  v9 = SystemTime;
  v10 = KiWaitAlways ^ _byteswap_uint64((unsigned __int64)Timer ^ __ROL8__(
                                                                    *((_QWORD *)Timer + 6) ^ KiWaitNever,
                                                                    KiWaitNever));
  v11 = -1;
  v45 = 0i64;
  if( (_DWORD)v5 )
  {
    v12 = -10000 * v5;
    v11 = 0;
    if( *((_BYTE *)Prcb + 12586) )
    {
      if( ++*((_DWORD *)Prcb + 8105) >= 0xBB8u )
      {
        v39 = *((_DWORD *)Prcb + 8106);
        *((_DWORD *)Prcb + 8105) = 0;
        if( v39 < 0x5F5E100 )
          *((_DWORD *)Prcb + 8106) = KeTimeIncrement + v39;
      }
      v12 -= *((unsigned int *)Prcb + 8106);
    }
    if( v12 + *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart - *((_QWORD *)Timer + 3) >= 0 )
      *((_QWORD *)Timer + 3) = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
    v13 = 0i64;
    LODWORD(v45) = *(_DWORD *)Timer;
    if( BYTE1(v45) >= 4u )
      v13 = (unsigned __int64)(BYTE1(v45) & 0xFC) << 16;
    if( (KiVelocityFlags & 0x2000) != 0 )
    {
      v14 = (char *)*((_QWORD *)Timer + 1);
      *((_WORD *)Timer + 29) = 1;
      v15 = (char *)Timer + 8;
      if( v14 == (char *)Timer + 8 )
        goto LABEL_9;
      while( 1 )
      {
        v30 = (unsigned __int8)v14[16] <= 1u;
        v31 = v14;
        v14 = *(char **)v14;
        if( v30 )
        {
          if( PsTimerResolutionActive(*(_QWORD *)(*((_QWORD *)v31 + 3) + 544i64)) )
            break;
        }
        if( v14 == v15 )
          goto LABEL_9;
      }
    }
    *((_WORD *)Timer + 29) = v4;
LABEL_9:
    BYTE1(v45) &= ~1u;
    BYTE3(v45) = 64;
    do
    {
      *((_QWORD *)Timer + 3) -= v12;
      BYTE2(v45) = (v13 + *((_QWORD *)Timer + 3)) >> 18;
      v16 = BYTE2(v45);
      *(_DWORD *)Timer = v45;
    }
    while( !KiInsertTimerTable(Prcb, Timer, (_KDPC *)v10, v16, 0i64) );
    v9 = SystemTime;
  }
  Flink = (_KWAIT_BLOCK *)*((_QWORD *)Timer + 1);
  v18 = (_KWAIT_BLOCK *)((char *)Timer + 8);
  *((_DWORD *)Timer + 1) = 1;
  if( v7 == 8 )
  {
    if( Flink == v18 )
    {
LABEL_14:
      *((_QWORD *)Timer + 2) = (char *)Timer + 8;
      v18->WaitListEntry.Flink = &v18->WaitListEntry;
      goto LABEL_15;
    }
    while( 1 )
    {
      v19 = Flink;
      Flink = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
      WaitType = v19->WaitType;
      if( WaitType == 1 )
      {
        WaitKey = v19->WaitKey;
      }
      else
      {
        if( WaitType == 2 )
        {
          v19->BlockState = 5;
          Object = v19->NotificationQueue;
          Entrya = (INT64)&Object->Header.WaitListHead;
          v19->WaitListEntry.Flink = 0i64;
          KeGetCurrentIrql();
          __writecr8(2ui64);
          Prcba = KeGetCurrentPrcb();
          v44 = *((_QWORD *)Prcba + 1);
          KiAcquireKobjectLockSafe(Object);
          p_Flink = (_QWORD *)Entrya;
          v28 = Object;
          if( (_QWORD *)*p_Flink == p_Flink
            || Object->CurrentCount >= Object->MaximumCount
            || *(_KQUEUE **)(v44 + 232) == Object && *(_BYTE *)(v44 + 643) == 15 )
          {
LABEL_52:
            SignalState = v28->Header.SignalState;
            v28->Header.SignalState = SignalState + 1;
            Blink = v28->EntryListHead.Blink;
            if( Blink->Flink != &v28->EntryListHead )
              goto LABEL_32;
            v19->WaitListEntry.Flink = &v28->EntryListHead;
            v19->WaitListEntry.Blink = Blink;
            Blink->Flink = &v19->WaitListEntry;
            v28->EntryListHead.Blink = &v19->WaitListEntry;
            if( !SignalState && (_QWORD *)*p_Flink != p_Flink )
            {
              KiWakeOtherQueueWaiters(Prcba, v28);
              v28 = Object;
            }
          }
          else
          {
            v29 = KiWakeQueueWaiter(Prcba, Object, (INT64)v19);
            v28 = Object;
            if( !v29 )
            {
              p_Flink = &Object->Header.WaitListHead.Flink;
              goto LABEL_52;
            }
          }
          _InterlockedAnd(&v28->Header.Lock, 0xFFFFFF7F);
          goto LABEL_26;
        }
        WaitKey = 256i64;
      }
      KiTryUnwaitThread(Prcb, v19, WaitKey, 0i64);
LABEL_26:
      if( Flink == v18 )
        goto LABEL_14;
    }
  }
  if( Flink != v18 )
  {
    while( 1 )
    {
      v22 = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
      v23 = Flink;
      Entry = &Flink->WaitListEntry;
      Flink = v22;
      v24 = (_KWAIT_BLOCK **)Entry->Blink;
      if( v22->WaitListEntry.Blink != Entry || *v24 != v23 )
LABEL_32:
        __fastfail(3u);
      *v24 = v22;
      v22->WaitListEntry.Blink = (_LIST_ENTRY *)v24;
      v25 = v23->WaitType;
      if( v25 != 1 )
        break;
      if( KiTryUnwaitThread(Prcb, v23, v23->WaitKey, 0i64) )
      {
        v26 = (*((_DWORD *)Timer + 1))-- == 1;
        if( v26 )
          goto LABEL_15;
      }
LABEL_39:
      if( Flink == v18 )
        goto LABEL_15;
    }
    if( v25 != 2 )
    {
      KiTryUnwaitThread(Prcb, v23, 256i64, 0i64);
      goto LABEL_39;
    }
    v23->BlockState = 5;
    Objecta = v23->NotificationQueue;
    p_WaitListHead = &Objecta->Header.WaitListHead;
    v23->WaitListEntry.Flink = 0i64;
    KeGetCurrentIrql();
    __writecr8(2ui64);
    Prcbb = KeGetCurrentPrcb();
    v44 = *((_QWORD *)Prcbb + 1);
    KiAcquireKobjectLockSafe(Objecta);
    v34 = p_WaitListHead;
    v35 = Objecta;
    if( v34->Flink != v34
      && Objecta->CurrentCount < Objecta->MaximumCount
      && (*(_KQUEUE **)(v44 + 232) != Objecta || *(_BYTE *)(v44 + 643) != 15) )
    {
      v38 = KiWakeQueueWaiter(Prcbb, Objecta, (INT64)Entry);
      v35 = Objecta;
      if( v38 )
        goto LABEL_67;
      v34 = &Objecta->Header.WaitListHead;
    }
    v36 = v35->Header.SignalState;
    v35->Header.SignalState = v36 + 1;
    v37 = v35->EntryListHead.Blink;
    if( v37->Flink != &v35->EntryListHead )
      goto LABEL_32;
    Entry->Flink = &v35->EntryListHead;
    Entry->Blink = v37;
    v37->Flink = Entry;
    v35->EntryListHead.Blink = Entry;
    if( !v36 && v34->Flink != v34 )
    {
      KiWakeOtherQueueWaiters(Prcbb, v35);
      v35 = Objecta;
    }
LABEL_67:
    _InterlockedAnd(&v35->Header.Lock, 0xFFFFFF7F);
    v26 = (*((_DWORD *)Timer + 1))-- == 1;
    if( v26 )
      goto LABEL_15;
    goto LABEL_39;
  }
LABEL_15:
  if( v10 )
  {
    if( v9 )
    {
      if( (!KiSerializeTimerExpiration || *(_WORD *)(v10 + 2) < 0x500u)
        && (*(_BYTE *)v10 != 26 || !*((_BYTE *)Prcb + 12584)) )
      {
        *((_QWORD *)Prcb + 1564) = v10;
        if( (*((_QWORD *)Prcb + 25) & *(_QWORD *)(v10 + 16)) == 0i64 )
          _interlockedbittestandset64((volatile signed __int32 *)(v10 + 16), *((unsigned __int8 *)Prcb + 209));
        goto LABEL_21;
      }
    }
    else
    {
      v9 = (_ULARGE_INTEGER *)&v43;
      v43 = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
    }
    KiInsertQueueDpc((_KDPC *)v10, (PVOID)*(_DWORD *)v9, (PVOID)*((unsigned int *)v9 + 1), Timer, v11);
    return;
  }
LABEL_21:
  _InterlockedAnd((volatile signed __int32 *)Timer, ~((v11 << 24) | 0x80));
}

Referenced by:

ExpSetTimerObject
KeSetTimerEx
KiAdjustTimerDueTimes
KiCommitThreadWait
KiProcessExpiredTimerList
KiResumeThread
KiSetTimerEx