KeRemoveQueueEx
NTSTATUS __fastcall KeRemoveQueueEx(UINT64 a1, INT8 a2, INT8 a3, INT64 a4, INT64 *EntryArray, UINT64 Count){
_ETHREAD *CurrentThread;
UINT64 v7;
__int64 v9;
unsigned __int8 CurrentIrql;
NTSTATUS v12;
_DISPATCHER_HEADER *volatile Queue;
char v14;
struct _KPRCB *v15;
$BA6907B96C27CBFB414D9A454222AF19 *v16;
INT64 v17;
_DISPATCHER_HEADER *v18;
int v19;
unsigned __int64 v20;
_LIST_ENTRY *v21;
_LIST_ENTRY *v22;
INT64 v23;
unsigned int v25;
__int64 *v26;
__int64 **v27;
__int64 v28;
__int64 v29;
__int64 **v30;
struct _KPRCB *CurrentPrcb;
unsigned __int64 WaitIrql;
_ETHREAD *v33;
NTSTATUS v34;
INT64 v35;
struct _KPRCB *v36;
unsigned __int64 v37;
_ETHREAD *v38;
__int64 ThreadTimerDelay;
unsigned __int64 v40;
struct _KPRCB *v41;
unsigned __int8 v42;
INT64 v43;
struct _KPRCB *v44;
_ETHREAD *NextThread;
char v46;
_DWORD *v47;
INT64 v48;
struct _KPRCB *v49;
_ETHREAD *v50;
char v51;
_DWORD *SchedulerAssist;
struct _KPRCB *v53;
_DWORD *v55;
int v56;
_DWORD *v57;
_LIST_ENTRY *Flink;
_LIST_ENTRY *Blink;
PVOID BugCheckParameter4;
INT64 v61;
INT64 v62;
UINT64 SpinCount;
UINT64 v64;
__int64 i;
__int64 v66;
_KDUE_TIME_TYPE TimeoutType;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v7 = 0i64;
v9 = a2;
v66 = 0i64;
if( !_bittestandreset((signed __int32 *)&CurrentThread->Tcb.116, 2u) )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentThread->Tcb.WaitIrql = CurrentIrql;
}
v12 = 1;
if( a4 )
{
if( *(int *)(a4 + 4) < 0 )
{
TimeoutType = DueTimeRelative;
v7 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart
- KUSER_SHARED_DATA.InterruptTimeBias
- (*(_QWORD *)a4
+ CurrentThread->Tcb.RelativeTimerBias);
}
else
{
v7 = *(_QWORD *)a4;
TimeoutType = DueTimeAbsolute;
}
}
else
{
TimeoutType = DueTimeNone;
}
Queue = CurrentThread->Tcb.Queue;
if( Queue == (_DISPATCHER_HEADER *volatile)a1 )
{
if( *(_DWORD *)(a1 + 4) )
{
v25 = *(_DWORD *)(a1 + 40);
if( v25 <= *(_DWORD *)(a1 + 44) )
{
LODWORD(v62) = 0;
while( _interlockedbittestandset((volatile signed __int32 *)a1, 7u) )
{
do
KeYieldProcessorEx((UINT64 *)&v62);
while( (*(_DWORD *)a1 & 0x80u) != 0 );
}
if( *(_DWORD *)(a1 + 4) && *(_DWORD *)(a1 + 40) <= *(_DWORD *)(a1 + 44) )
{
v26 = *(__int64 **)(a1 + 24);
v27 = (__int64 **)(a1 + 24);
v28 = 0i64;
do
{
--*(_DWORD *)(a1 + 4);
v29 = *v26;
if( !*v26 )
KeBugCheckEx(0x96u, v26, (PVOID)a1, *(&WheapDeferredInternalLogsEventLock + 337), (PVOID)v26[2]);
v30 = (__int64 **)v26[1];
if( *(__int64 **)(v29 + 8) != v26 || *v30 != v26 )
goto LABEL_160;
*v30 = (__int64 *)v29;
*(_QWORD *)(v29 + 8) = v30;
*v26 = 0i64;
EntryArray[v28] = (INT64)v26;
v28 = (unsigned int)(v28 + 1);
v26 = *v27;
}
while( *v27 != (__int64 *)v27 && (unsigned int)v28 < (unsigned int)Count );
if( (_DWORD)v28 )
{
_InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
CurrentPrcb = KeGetCurrentPrcb();
WaitIrql = CurrentThread->Tcb.WaitIrql;
if( (unsigned __int8)WaitIrql >= 2u )
{
if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
return v28;
}
v33 = CurrentPrcb->CurrentThread;
if( CurrentPrcb->NextThread )
{
KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
v44 = KeGetCurrentPrcb();
HIDWORD(v62) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v62 + 4));
while( CurrentPrcb->PrcbLock );
SchedulerAssist = v44->SchedulerAssist;
if( SchedulerAssist && v44->NestingLevel <= 1u )
++SchedulerAssist[6];
}
NextThread = CurrentPrcb->NextThread;
CurrentPrcb->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation(
(INT64)CurrentPrcb,
(INT64)v33,
0i64,
v43,
(INT64)BugCheckParameter4,
v61,
v62);
_enable();
CurrentPrcb->CurrentThread = NextThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
- NextThread->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.WaitBlockFill6[68] = 2;
v33->Tcb.WaitReason = 32;
v33->Tcb.WaitIrql = WaitIrql;
KiQueueReadyThread(CurrentPrcb, &v33->Tcb);
KiSwapContext();
if( !v46 )
goto LABEL_51;
}
else if( (v33->Tcb._bf_0 & 0x40) == 0 )
{
LABEL_51:
__writecr8(WaitIrql);
return v28;
}
__writecr8(1ui64);
v33->Tcb._bf_0 &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
goto LABEL_51;
}
}
_InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
goto LABEL_9;
}
}
if( a4 && !*(_QWORD *)a4 )
{
if( (*(_BYTE *)(a1 + 1) & 1) != 0 )
{
*EntryArray = 128i64;
}
else
{
if( a3 )
{
v53 = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( CurrentThread->Tcb.ThreadLock );
v55 = v53->SchedulerAssist;
if( v55 && v53->NestingLevel <= 1u )
{
v56 = v55[6] + 1;
v55[6] = v56;
}
}
}
v34 = KiTestForAlertPending(&CurrentThread->Tcb, a3, v9, 1ui64);
v35 = v34;
if( !v34 )
v35 = 258i64;
*EntryArray = v35;
if( a3 )
KiReleaseThreadLockSafe((INT64)CurrentThread);
}
v36 = KeGetCurrentPrcb();
v37 = CurrentThread->Tcb.WaitIrql;
if( (unsigned __int8)v37 >= 2u )
{
if( v36->NextThread && !v36->DpcRoutineActive )
KiRequestSoftwareInterrupt(v36, 2);
return v12;
}
v38 = v36->CurrentThread;
if( v36->NextThread )
{
KiAbProcessContextSwitch(&v36->CurrentThread->Tcb, 0i64);
v49 = KeGetCurrentPrcb();
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v36->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( v36->PrcbLock );
v57 = v49->SchedulerAssist;
if( v57 && v49->NestingLevel <= 1u )
++v57[6];
}
v50 = v36->NextThread;
v36->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation((INT64)v36, (INT64)v38, 0i64, v48, (INT64)BugCheckParameter4, v61, v62);
_enable();
v36->CurrentThread = v50;
if( v50->Tcb.WaitBlockFill6[68] == 1 )
v50->Tcb.ReadyTime = v50->Tcb.ReadyTime
- v50->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
v50->Tcb.WaitBlockFill6[68] = 2;
v38->Tcb.WaitReason = 32;
v38->Tcb.WaitIrql = v37;
KiQueueReadyThread(v36, &v38->Tcb);
KiSwapContext();
if( !v51 )
goto LABEL_64;
}
else if( (v38->Tcb._bf_0 & 0x40) == 0 )
{
LABEL_64:
__writecr8(v37);
return v12;
}
__writecr8(1ui64);
v38->Tcb._bf_0 &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
goto LABEL_64;
}
}
LABEL_9:
for( i = CurrentThread->Tcb.WaitIrql; ; CurrentThread->Tcb.WaitIrql = i )
{
v14 = i;
while( 1 )
{
CurrentThread->Tcb._bf_0 &= ~0x10u;
CurrentThread->Tcb.WaitRegister.Flags = 0;
CurrentThread->Tcb.WaitMode = v9;
if( a3 )
CurrentThread->Tcb._bf_0 |= 0x10u;
v15 = KeGetCurrentPrcb();
LODWORD(v64) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx(&v64);
while( CurrentThread->Tcb.ThreadLock );
v47 = v15->SchedulerAssist;
if( v47 && v15->NestingLevel <= 1u )
++v47[6];
}
if( !CurrentThread->Tcb.ApcState.KernelApcPending || CurrentThread->Tcb.SpecialApcDisable || v14 )
break;
KiReleaseThreadLockSafe((INT64)CurrentThread);
__writecr8(1ui64);
KiDeliverApc(0, 0i64, 0i64);
KeGetCurrentIrql();
__writecr8(2ui64);
CurrentThread->Tcb.WaitIrql = 0;
}
v16 = &CurrentThread->Tcb.320;
if( !a3 )
{
if( (CurrentThread->Tcb.ApcState.UserApcPendingAll & 2) == 0 || !(_BYTE)v9 )
{
LABEL_21:
CurrentThread->Tcb.WaitBlockFill6[68] = 5;
CurrentThread->Tcb.WaitReason = 15;
CurrentThread->Tcb.WaitBlock[2].SpareLong = KUSER_SHARED_DATA.TickCount.LowPart;
CurrentThread->Tcb.ThreadLock = 0i64;
v17 = 0i64;
goto LABEL_22;
}
goto LABEL_91;
}
if( CurrentThread->Tcb.Alerted[v9] )
{
CurrentThread->Tcb.Alerted[v9] = 0;
v17 = 257i64;
goto LABEL_92;
}
if( (_BYTE)v9
&& (unsigned __int8 *)CurrentThread->Tcb.ApcState.ApcListHead[1].Flink != &CurrentThread->Tcb.ApcStateFill[16] )
{
CurrentThread->Tcb.ApcState.UserApcPendingAll |= 2u;
LABEL_91:
v17 = 192i64;
goto LABEL_92;
}
if( !CurrentThread->Tcb.Alerted[0] )
goto LABEL_21;
CurrentThread->Tcb.Alerted[0] = 0;
v17 = 257i64;
LABEL_92:
KiReleaseThreadLockSafe((INT64)CurrentThread);
KiCheckForThreadDispatch(KeGetCurrentPrcb(), i);
LABEL_22:
if( v17 )
{
*EntryArray = v17;
return v12;
}
v18 = CurrentThread->Tcb.Queue;
if( (_DISPATCHER_HEADER *)a1 != v18 )
KiSwitchQueue(&CurrentThread->Tcb, (_KQUEUE *)a1, v18);
CurrentThread->Tcb.WaitBlock[0].WaitType = 3;
CurrentThread->Tcb.WaitBlockFill4[17] = 4;
v19 = 0;
CurrentThread->Tcb.WaitBlock[0].WaitKey = 128;
CurrentThread->Tcb.WaitBlock[0].Object = (void *)a1;
while( _interlockedbittestandset((volatile signed __int32 *)a1, 7u) )
{
do
{
++v19;
_mm_pause();
}
while( (*(_DWORD *)a1 & 0x80u) != 0 );
}
if( *(_DWORD *)(a1 + 4) )
{
if( *(_DWORD *)(a1 + 40) <= *(_DWORD *)(a1 + 44) )
{
LODWORD(v28) = (unsigned int)KiAttemptFastRemoveQueue(
(_KQUEUE *)a1,
(_LIST_ENTRY **)EntryArray,
(unsigned int)Count);
if( (_DWORD)v28 )
{
_InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
goto LABEL_85;
}
}
}
if( (*(_BYTE *)(a1 + 1) & 1) != 0 )
break;
v20 = v7;
if( TimeoutType == DueTimeRelative )
{
ThreadTimerDelay = CurrentThread->Tcb.ThreadTimerDelay;
v40 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart
- CurrentThread->Tcb.RelativeTimerBias
- KUSER_SHARED_DATA.InterruptTimeBias;
v20 = v7;
if( CurrentThread->Tcb.WaitMode
&& !CurrentThread->Tcb.WaitBlock[3].SpareLong
&& !CurrentThread->Tcb.WaitIrql
&& !CurrentThread->Tcb.ApcState.InProgressFlags
&& (_DWORD)ThreadTimerDelay )
{
v20 = ThreadTimerDelay + v7;
}
}
else
{
if( TimeoutType == DueTimeNone )
goto LABEL_30;
if( !v7 )
{
LABEL_106:
_InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
*EntryArray = 258i64;
goto LABEL_107;
}
v40 = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
}
if( v40 > v20 )
goto LABEL_106;
LABEL_30:
_InterlockedDecrement((volatile signed __int32 *)(a1 + 40));
v21 = (_LIST_ENTRY *)(a1 + 8);
v22 = *(_LIST_ENTRY **)(a1 + 8);
if( v22->Blink != (_LIST_ENTRY *)(a1 + 8) )
goto LABEL_160;
v16->WaitBlock[0].WaitListEntry.Flink = v22;
CurrentThread->Tcb.WaitBlock[0].WaitListEntry.Blink = v21;
v22->Blink = (_LIST_ENTRY *)v16;
v21->Flink = (_LIST_ENTRY *)v16;
_InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
CurrentThread->Tcb.WaitBlockCount = 1;
KiCommitThreadWait(CurrentThread, CurrentThread->Tcb.WaitBlock, TimeoutType, v7);
CurrentThread->Tcb.WaitReason = 0;
if( v23 != 256 )
{
*EntryArray = v23;
if( (unsigned int)Count > 1
&& (unsigned __int64)(v23 - 257) > 1
&& v23 != 128
&& v23 != 192
&& *(_DWORD *)(a1 + 4) )
{
v42 = KeGetCurrentIrql();
__writecr8(2ui64);
KiAcquireKobjectLockSafe((VOID *)a1);
if( *(_DWORD *)(a1 + 4) )
v12 = (unsigned int)KiAttemptFastRemoveQueue(
(_KQUEUE *)a1,
(_LIST_ENTRY **)EntryArray + 1,
(unsigned int)(Count - 1))
+ 1;
_InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
__writecr8(v42);
}
return v12;
}
i = KeGetCurrentIrql();
__writecr8(2ui64);
}
if( !CurrentThread->Tcb.Queue )
goto LABEL_159;
Flink = CurrentThread->Tcb.QueueListEntry.Flink;
Blink = CurrentThread->Tcb.QueueListEntry.Blink;
if( Flink->Blink != &CurrentThread->Tcb.QueueListEntry || Blink->Flink != &CurrentThread->Tcb.QueueListEntry )
LABEL_160:
__fastfail(3u);
Blink->Flink = Flink;
Flink->Blink = Blink;
CurrentThread->Tcb.Queue = 0i64;
LABEL_159:
_InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
*EntryArray = 128i64;
LABEL_107:
LODWORD(v28) = 1;
LABEL_85:
CurrentThread->Tcb.WaitReason = 0;
v41 = KeGetCurrentPrcb();
if( v41->DeferredReadyListHead.Next )
KiProcessThreadWaitList(v41, AdjustUnwait, 0i64, 2ui64);
KiFastExitThreadWait(v41, &CurrentThread->Tcb, 1u);
return v28;
}Referenced by:
IoRemoveIoCompletion
KeRemoveQueue