KiExpireTimer2

void __fastcall KiExpireTimer2(__int64 a1, __int64 a2, unsigned __int64 a3, _DWORD *a4){
  __int64 v4; 
  unsigned __int64 v6; 
  __int64 v7; 
  int v8; 
  __int64 v9; 
  _KWAIT_BLOCK *v10; 
  char v11; 
  _KWAIT_BLOCK *v12; 
  _LIST_ENTRY *Flink; 
  _KWAIT_BLOCK *v14; 
  _LIST_ENTRY *Blink; 
  char v16; 
  __int64 v17; 
  char v18; 
  __int64 v19; 
  unsigned __int8 WaitType; 
  _KQUEUE *NotificationQueue; 
  _LIST_ENTRY *p_WaitListHead; 
  struct _KPRCB *CurrentPrcb; 
  bool v24; 
  void(__fastcall *v25)(__int64, unsigned __int64); 
  signed __int32 v26; 
  int v27; 
  signed __int32 v28; 
  signed __int32 v29; 
  int SignalState; 
  _LIST_ENTRY *v31; 
  unsigned __int64 v32; 
  _DWORD *v33; 
  INT64 v34; 
  INT64 v35; 
  __int64 v36; 
  _DWORD *v37; 
  signed __int32 v38; 
  signed __int32 v39; 
  __int64 v40; 
  unsigned __int64 v41; 
  __int64 *v42; 
  __int64 v43; 
  bool v44; 
  __int64 *v45; 
  unsigned __int64 v46; 
  unsigned __int64 v47; 
  char v48; 
  unsigned __int64 v49; 
  __int64 v50; 
  __int64 v51; 
  unsigned __int64 v52; 
  __int64 v53; 
  _KWAIT_BLOCK *v54; 
  unsigned __int8 v55; 
  INT64 WaitKey; 
  _KQUEUE *v57; 
  _LIST_ENTRY *v58; 
  __int64 v59; 
  _KPRCB *v60; 
  int v61; 
  _LIST_ENTRY *v62; 
  signed __int32 v63; 
  char v64; 
  char v65; 
  _KPRCB *Prcb; 
  __int64 v67; 
  INT64 v68; 
  ULONG_PTR BugCheckParameter3; 
  INT64 CurrentQpc; 
  _DWORD *v71; 
  INT64 v72; 
  __int64 v73; 
  __int64 v74; 
  __int64 v75; 
  __int64 v76; 
  __int64 v77; 
  __int64 v78; 
  LARGE_INTEGER v79[2]; 
  __int128 v80; 
  v4 = *(_QWORD *)(a2 + 8);
  v71 = a4;
  v68 = a2;
  v6 = a3;
  v72 = 0i64;
  v7 = a2;
  v73 = 0i64;
  v8 = 0;
  v75 = 0i64;
  v76 = 0i64;
  v77 = 0i64;
  v78 = 0i64;
  *(_OWORD *)&v79[0].LowPart = 0i64;
  CurrentQpc = 0i64;
  v80 = 0i64;
  LODWORD(BugCheckParameter3) = *(_DWORD *)(v4 + 484);
  v74 = 0i64;
  v64 = 0;
  v67 = v4;
  v9 = *(_QWORD *)(a1 + 88);
  if( !v9 || (*(_BYTE *)(a1 + 1) & 0x20) != 0 )
    goto LABEL_2;
  v16 = *(_BYTE *)(a1 + 129);
  if( (v16 & 4) != 0 )
  {
    LODWORD(v47) = RtlGetInterruptTimePrecise(&CurrentQpc);
    v9 = *(_QWORD *)(a1 + 88);
    v6 = v47;
    v16 = *(_BYTE *)(a1 + 129);
  }
  v17 = v9 + v6;
  if( v9 + v6 < v6 || v17 == -1 )
  {
    v17 = -2i64;
    v18 = 1;
  }
  else
  {
    v18 = 0;
  }
  v65 = v18;
  if( (v16 & 0xE) == 0 )
  {
    if( (KiVelocityFlags & 0x2000) != 0 )
    {
      v42 = *(__int64 **)(a1 + 8);
      v43 = a1 + 8;
      if( v42 == (__int64 *)(a1 + 8) )
      {
LABEL_54:
        if( (v16 & 0x10) == 0 )
          goto LABEL_13;
        v48 = v16 & 0xEF;
        goto LABEL_69;
      }
      while( 1 )
      {
        v44 = *((_BYTE *)v42 + 16) <= 1u;
        v45 = v42;
        v42 = (__int64 *)*v42;
        if( v44 )
        {
          if( PsTimerResolutionActive(*(_QWORD *)(v45[3] + 544)) )
            break;
        }
        if( v42 == (__int64 *)v43 )
          goto LABEL_54;
      }
      if( (v16 & 0x10) != 0 )
        goto LABEL_13;
    }
    else if( (v16 & 0x10) != 0 )
    {
      goto LABEL_13;
    }
    v48 = v16 | 0x10;
LABEL_69:
    *(_BYTE *)(a1 + 129) = v48;
    KiUpdateTimer2Collections((BYTE *)a1);
  }
LABEL_13:
  v19 = *(_QWORD *)(a1 + 80);
  if( v19 != -1 )
  {
    v40 = v19 - *(_QWORD *)(a1 + 72);
    if( v40 )
    {
      v46 = v40 + v6;
      if( v40 + v6 < v6 || v46 == -1i64 )
        v46 = -2i64;
      v41 = v46 + *(_QWORD *)(a1 + 88);
      if( v41 < v46 || v41 == -1i64 )
        v41 = -2i64;
    }
    else
    {
      v41 = v17;
    }
    *(_QWORD *)(a1 + 80) = v41;
  }
  *(_QWORD *)(a1 + 72) = v17;
  while( !KiInsertTimer2(a1, 0, &v64) )
  {
    if( v18 )
      goto LABEL_2;
    v49 = *(_QWORD *)(a1 + 72);
    v50 = *(_QWORD *)(a1 + 88);
    v51 = v49 + v50;
    if( v49 + v50 < v49 || v51 == -1 )
    {
      v51 = -2i64;
      v18 = 1;
    }
    *(_QWORD *)(a1 + 72) = v51;
    v52 = *(_QWORD *)(a1 + 80);
    v65 = v18;
    if( v52 != -1i64 )
    {
      v53 = v52 + v50;
      if( v52 + v50 < v52 || v53 == -1 )
        v53 = -2i64;
      *(_QWORD *)(a1 + 80) = v53;
    }
  }
  v8 = 1;
LABEL_2:
  v10 = (_KWAIT_BLOCK *)(a1 + 8);
  v11 = *(_BYTE *)a1 & 0x7F;
  v12 = *(_KWAIT_BLOCK **)(a1 + 8);
  *(_DWORD *)(a1 + 4) = 1;
  if( v11 == 25 )
  {
    if( v12 == v10 )
      goto LABEL_26;
    while( 1 )
    {
      Flink = v12->WaitListEntry.Flink;
      v14 = v12;
      v12 = (_KWAIT_BLOCK *)Flink;
      Blink = v14->WaitListEntry.Blink;
      if( (_KWAIT_BLOCK *)Flink->Blink != v14 || (_KWAIT_BLOCK *)Blink->Flink != v14 )
        goto LABEL_5;
      Blink->Flink = Flink;
      Flink->Blink = Blink;
      WaitType = v14->WaitType;
      if( WaitType == 1 )
      {
        if( KiTryUnwaitThread((_KPRCB *)v7, v14, v14->WaitKey, 0i64) )
        {
          v24 = (*(_DWORD *)(a1 + 4))-- == 1;
          if( v24 )
          {
LABEL_25:
            v4 = v67;
            goto LABEL_26;
          }
        }
      }
      else if( WaitType == 2 )
      {
        v14->BlockState = 5;
        NotificationQueue = v14->NotificationQueue;
        v14->WaitListEntry.Flink = 0i64;
        p_WaitListHead = &NotificationQueue->Header.WaitListHead;
        KeGetCurrentIrql();
        __writecr8(2ui64);
        CurrentPrcb = KeGetCurrentPrcb();
        Prcb = (_KPRCB *)*((_QWORD *)CurrentPrcb + 1);
        KiAcquireKobjectLockSafe(NotificationQueue);
        if( p_WaitListHead->Flink == p_WaitListHead
          || NotificationQueue->CurrentCount >= NotificationQueue->MaximumCount
          || *((_KQUEUE **)Prcb + 29) == NotificationQueue && *((_BYTE *)Prcb + 643) == 15
          || !KiWakeQueueWaiter(CurrentPrcb, NotificationQueue, (INT64)v14) )
        {
          SignalState = NotificationQueue->Header.SignalState;
          NotificationQueue->Header.SignalState = SignalState + 1;
          v31 = NotificationQueue->EntryListHead.Blink;
          if( v31->Flink != &NotificationQueue->EntryListHead )
            goto LABEL_5;
          v14->WaitListEntry.Flink = &NotificationQueue->EntryListHead;
          v14->WaitListEntry.Blink = v31;
          v31->Flink = &v14->WaitListEntry;
          NotificationQueue->EntryListHead.Blink = &v14->WaitListEntry;
          if( !SignalState && p_WaitListHead->Flink != p_WaitListHead )
            KiWakeOtherQueueWaiters(CurrentPrcb, NotificationQueue);
        }
        _InterlockedAnd(&NotificationQueue->Header.Lock, 0xFFFFFF7F);
        v24 = (*(_DWORD *)(a1 + 4))-- == 1;
        v7 = v68;
        if( v24 )
          goto LABEL_25;
      }
      else
      {
        KiTryUnwaitThread((_KPRCB *)v7, v14, 256i64, 0i64);
      }
      if( v12 == (_KWAIT_BLOCK *)(a1 + 8) )
        goto LABEL_25;
    }
  }
  if( v12 != v10 )
  {
    while( 1 )
    {
      v54 = v12;
      v12 = (_KWAIT_BLOCK *)v12->WaitListEntry.Flink;
      v55 = v54->WaitType;
      if( v55 == 1 )
      {
        WaitKey = v54->WaitKey;
LABEL_98:
        KiTryUnwaitThread((_KPRCB *)v7, v54, WaitKey, 0i64);
        goto LABEL_99;
      }
      if( v55 != 2 )
      {
        WaitKey = 256i64;
        goto LABEL_98;
      }
      v54->BlockState = 5;
      v57 = v54->NotificationQueue;
      v54->WaitListEntry.Flink = 0i64;
      v58 = &v57->Header.WaitListHead;
      KeGetCurrentIrql();
      __writecr8(2ui64);
      Prcb = KeGetCurrentPrcb();
      v59 = *((_QWORD *)Prcb + 1);
      KiAcquireKobjectLockSafe(v57);
      if( v58->Flink == v58
        || v57->CurrentCount >= v57->MaximumCount
        || *(_KQUEUE **)(v59 + 232) == v57 && *(_BYTE *)(v59 + 643) == 15 )
      {
        break;
      }
      v60 = Prcb;
      if( !KiWakeQueueWaiter(Prcb, v57, (INT64)v54) )
        goto LABEL_92;
LABEL_96:
      _InterlockedAnd(&v57->Header.Lock, 0xFFFFFF7F);
      v7 = v68;
LABEL_99:
      v10 = (_KWAIT_BLOCK *)(a1 + 8);
      if( v12 == (_KWAIT_BLOCK *)(a1 + 8) )
      {
        v4 = v67;
        goto LABEL_62;
      }
    }
    v60 = Prcb;
LABEL_92:
    v61 = v57->Header.SignalState;
    v57->Header.SignalState = v61 + 1;
    v62 = v57->EntryListHead.Blink;
    if( v62->Flink != &v57->EntryListHead )
LABEL_5:
      __fastfail(3u);
    v54->WaitListEntry.Flink = &v57->EntryListHead;
    v54->WaitListEntry.Blink = v62;
    v62->Flink = &v54->WaitListEntry;
    v57->EntryListHead.Blink = &v54->WaitListEntry;
    if( !v61 && v58->Flink != v58 )
      KiWakeOtherQueueWaiters(v60, v57);
    goto LABEL_96;
  }
LABEL_62:
  v10->WaitListEntry.Blink = &v10->WaitListEntry;
  v10->WaitListEntry.Flink = &v10->WaitListEntry;
LABEL_26:
  v25 = (void(__fastcall *)(__int64, unsigned __int64))(KiWaitAlways ^ _byteswap_uint64(a1 ^ __ROL8__(
                                                                                                KiWaitNever ^ *(_QWORD *)(a1 + 96),
                                                                                                KiWaitNever)));
  if( v25 )
  {
    v32 = KiWaitAlways ^ _byteswap_uint64(a1 ^ __ROL8__(KiWaitNever ^ *(_QWORD *)(a1 + 104), KiWaitNever));
    KiUpdateTimer2Flags((_KTIMER2 *)a1, v8 | 0x10u, 0i64);
    if( *(_QWORD *)(v7 + 11528) )
      KiProcessThreadWaitList((struct KPRCB *)v7, 1, 0);
    v33 = v71;
    v34 = v68;
    v35 = v68;
    v36 = ((*v71)++ & 0xF) + 1i64;
    v37 = &v33[4 * v36];
    *(_QWORD *)v37 = v25;
    v37[2] = KUSER_SHARED_DATA.TickCount.LowPart;
    *(_DWORD *)(v35 + 32412) = 0;
    KiResetGlobalDpcWatchdogProfiler(v35);
    *(_BYTE *)(v34 + 12586) = 1;
    v25(a1, v32);
    *(_BYTE *)(v34 + 12586) = 0;
    v37[3] = KUSER_SHARED_DATA.TickCount.LowPart;
    _m_prefetchw((const void *)a1);
    v38 = *(_DWORD *)a1;
    do
    {
      v39 = v38;
      v38 = _InterlockedCompareExchange((volatile signed __int32 *)a1, v38 & 0xFFFFEFFF, v38);
    }
    while( v39 != v38 );
    if( (v38 & 0x2F00) == 0x2000 )
      goto LABEL_29;
  }
  else
  {
    v26 = *(_DWORD *)a1;
    v27 = v8 << 8;
    v28 = v27 | *(_DWORD *)a1 & 0xFFFFF07F;
    v29 = _InterlockedCompareExchange((volatile signed __int32 *)a1, v28, *(_DWORD *)a1);
    if( v26 != v29 )
    {
      do
      {
        v63 = v29;
        v28 = v27 | v29 & 0xFFFFF07F;
        v29 = _InterlockedCompareExchange((volatile signed __int32 *)a1, v28, v29);
      }
      while( v63 != v29 );
    }
    if( (v28 & 0x3F00) == 0x2000 )
LABEL_29:
      KiFinalizeTimer2Disablement((_KTIMER2 *)a1);
  }
  if( (_DWORD)BugCheckParameter3 != *(_DWORD *)(v4 + 484) )
    KeBugCheckEx(0xC7u, 5ui64, (ULONG_PTR)v25, (unsigned int)BugCheckParameter3, *(unsigned int *)(v4 + 484));
}

Referenced by:

KiTimer2Expiration