KeRemoveQueueEx
ULONG __stdcall KeRemoveQueueEx(
PKQUEUE Queue,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout,
PLIST_ENTRY *EntryArray,
ULONG Count){
_ETHREAD *CurrentThread;
__int64 QuadPart;
__int64 v9;
unsigned __int8 CurrentIrql;
ULONG v12;
struct _KQUEUE *v13;
char v14;
struct _KPRCB *v15;
_LIST_ENTRY *v16;
__int64 v17;
int v18;
unsigned __int64 v19;
_LIST_ENTRY *p_WaitListHead;
_LIST_ENTRY *v21;
_LIST_ENTRY *v22;
unsigned int CurrentCount;
_LIST_ENTRY *Flink;
_LIST_ENTRY *p_EntryListHead;
__int64 v27;
_LIST_ENTRY *v28;
_LIST_ENTRY *Blink;
struct _KPRCB *CurrentPrcb;
unsigned __int64 v31;
ULONG_PTR v32;
int v33;
__int64 v34;
struct _KPRCB *v35;
unsigned __int64 v36;
ULONG_PTR v37;
__int64 v38;
unsigned __int64 v39;
struct _KPRCB *v40;
unsigned __int8 v41;
struct _KPRCB *v42;
__int64 v43;
__int64 v44;
__int64 v45;
struct _KPRCB *v46;
__int64 v47;
__int64 v48;
__int64 v49;
struct _KPRCB *v50;
__int64 v52;
int v53;
__int64 v54;
__int64 v55;
_ETHREAD **v56;
UINT64 SpinCount;
UINT64 v58;
UINT64 v59;
__int64 i;
__int64 v61;
int v63;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
QuadPart = 0i64;
v9 = WaitMode;
v61 = 0i64;
if( !_bittestandreset((signed __int32 *)CurrentThread + 29, 2u) )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
*((_BYTE *)CurrentThread + 390) = CurrentIrql;
}
v12 = 1;
if( Timeout )
{
if( Timeout->HighPart < 0 )
{
v63 = 2;
QuadPart = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart
- KUSER_SHARED_DATA.InterruptTimeBias
- (Timeout->QuadPart
+ *((_QWORD *)CurrentThread + 31));
}
else
{
QuadPart = Timeout->QuadPart;
v63 = 1;
}
}
else
{
v63 = 0;
}
v13 = (struct _KQUEUE *)*((_QWORD *)CurrentThread + 29);
if( v13 == Queue )
{
if( Queue->Header.SignalState )
{
CurrentCount = Queue->CurrentCount;
if( CurrentCount <= Queue->MaximumCount )
{
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset(&Queue->Header.Lock, 7u) )
{
do
KeYieldProcessorEx(&SpinCount);
while( (Queue->Header.LockNV & 0x80u) != 0 );
}
if( Queue->Header.SignalState && Queue->CurrentCount <= Queue->MaximumCount )
{
Flink = Queue->EntryListHead.Flink;
p_EntryListHead = &Queue->EntryListHead;
v27 = 0i64;
do
{
--Queue->Header.SignalState;
v28 = Flink->Flink;
if( !Flink->Flink )
KeBugCheckEx(0x96u, (ULONG_PTR)Flink, (ULONG_PTR)Queue, ExWorkerQueue, (ULONG_PTR)Flink[1].Flink);
Blink = Flink->Blink;
if( v28->Blink != Flink || Blink->Flink != Flink )
goto LABEL_160;
Blink->Flink = v28;
v28->Blink = Blink;
Flink->Flink = 0i64;
EntryArray[v27] = Flink;
v27 = (unsigned int)(v27 + 1);
Flink = p_EntryListHead->Flink;
}
while( p_EntryListHead->Flink != p_EntryListHead && (unsigned int)v27 < Count );
if( (_DWORD)v27 )
{
_InterlockedAnd(&Queue->Header.Lock, 0xFFFFFF7F);
CurrentPrcb = KeGetCurrentPrcb();
v31 = *((unsigned __int8 *)CurrentThread + 390);
if( (unsigned __int8)v31 >= 2u )
{
if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
return v27;
}
v32 = *((_QWORD *)CurrentPrcb + 1);
if( *((_QWORD *)CurrentPrcb + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
v42 = KeGetCurrentPrcb();
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *((_QWORD *)CurrentPrcb + 6) );
v49 = *((_QWORD *)v42 + 4247);
if( v49 && *((_BYTE *)v42 + 32) <= 1u )
++*(_DWORD *)(v49 + 24);
}
v43 = *((_QWORD *)CurrentPrcb + 2);
*((_QWORD *)CurrentPrcb + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v32, 0i64);
_enable();
*((_QWORD *)CurrentPrcb + 1) = v43;
if( *(_BYTE *)(v43 + 388) == 1 )
{
v44 = (unsigned int)(*(_DWORD *)(v43 + 132) - *(_DWORD *)(v43 + 436));
*(_DWORD *)(v43 + 132) = v44 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v43 + 388) = 2;
*(_BYTE *)(v32 + 643) = 32;
*(_BYTE *)(v32 + 390) = v31;
KiQueueReadyThread((__int64)CurrentPrcb, v32, v44);
if( !KiSwapContext((PKTHREAD)v32, (PKTHREAD)v43) )
goto LABEL_51;
}
else if( (*(_DWORD *)(v32 + 116) & 0x40) == 0 )
{
LABEL_51:
__writecr8(v31);
return v27;
}
__writecr8(1ui64);
*(_DWORD *)(v32 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
goto LABEL_51;
}
}
_InterlockedAnd(&Queue->Header.Lock, 0xFFFFFF7F);
goto LABEL_9;
}
}
if( Timeout && !Timeout->QuadPart )
{
if( (Queue->Header.Signalling & 1) != 0 )
{
*EntryArray = (PLIST_ENTRY)128;
}
else
{
if( Alertable )
{
v50 = KeGetCurrentPrcb();
LODWORD(v58) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentThread + 16, 0i64) )
{
do
KeYieldProcessorEx(&v58);
while( *((_QWORD *)CurrentThread + 8) );
v52 = *((_QWORD *)v50 + 4247);
if( v52 && *((_BYTE *)v50 + 32) <= 1u )
{
v53 = *(_DWORD *)(v52 + 24) + 1;
*(_DWORD *)(v52 + 24) = v53;
}
}
}
v33 = KiTestForAlertPending((__int64)CurrentThread, Alertable, v9, 1);
v34 = v33;
if( !v33 )
v34 = 258i64;
*EntryArray = (PLIST_ENTRY)v34;
if( Alertable )
KiReleaseThreadLockSafe((INT64)CurrentThread);
}
v35 = KeGetCurrentPrcb();
v36 = *((unsigned __int8 *)CurrentThread + 390);
if( (unsigned __int8)v36 >= 2u )
{
if( *((_QWORD *)v35 + 2) && !*((_BYTE *)v35 + 12586) )
KiRequestSoftwareInterrupt(v35, 2);
return v12;
}
v37 = *((_QWORD *)v35 + 1);
if( *((_QWORD *)v35 + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)v35 + 1), 0i64);
v46 = KeGetCurrentPrcb();
HIDWORD(v58) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v35 + 12, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v58 + 4));
while( *((_QWORD *)v35 + 6) );
v54 = *((_QWORD *)v46 + 4247);
if( v54 && *((_BYTE *)v46 + 32) <= 1u )
++*(_DWORD *)(v54 + 24);
}
v47 = *((_QWORD *)v35 + 2);
*((_QWORD *)v35 + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(v35, (_KTHREAD *)v37, 0i64);
_enable();
*((_QWORD *)v35 + 1) = v47;
if( *(_BYTE *)(v47 + 388) == 1 )
{
v48 = (unsigned int)(*(_DWORD *)(v47 + 132) - *(_DWORD *)(v47 + 436));
*(_DWORD *)(v47 + 132) = v48 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v47 + 388) = 2;
*(_BYTE *)(v37 + 643) = 32;
*(_BYTE *)(v37 + 390) = v36;
KiQueueReadyThread((__int64)v35, v37, v48);
if( !KiSwapContext((PKTHREAD)v37, (PKTHREAD)v47) )
goto LABEL_64;
}
else if( (*(_DWORD *)(v37 + 116) & 0x40) == 0 )
{
LABEL_64:
__writecr8(v36);
return v12;
}
__writecr8(1ui64);
*(_DWORD *)(v37 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
goto LABEL_64;
}
}
LABEL_9:
for( i = *((unsigned __int8 *)CurrentThread + 390); ; *((_BYTE *)CurrentThread + 390) = i )
{
v14 = i;
while( 1 )
{
*((_DWORD *)CurrentThread + 29) &= ~0x10u;
*((_BYTE *)CurrentThread + 112) = 0;
*((_BYTE *)CurrentThread + 391) = v9;
if( Alertable )
*((_DWORD *)CurrentThread + 29) |= 0x10u;
v15 = KeGetCurrentPrcb();
LODWORD(v59) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentThread + 16, 0i64) )
{
do
KeYieldProcessorEx(&v59);
while( *((_QWORD *)CurrentThread + 8) );
v45 = *((_QWORD *)v15 + 4247);
if( v45 && *((_BYTE *)v15 + 32) <= 1u )
++*(_DWORD *)(v45 + 24);
}
if( !*((_BYTE *)CurrentThread + 193) || *((_WORD *)CurrentThread + 243) || v14 )
break;
KiReleaseThreadLockSafe((INT64)CurrentThread);
__writecr8(1ui64);
KiDeliverApc(0, 0i64, 0i64);
KeGetCurrentIrql();
__writecr8(2ui64);
*((_BYTE *)CurrentThread + 390) = 0;
}
v16 = (_LIST_ENTRY *)((char *)CurrentThread + 320);
if( !Alertable )
{
if( (*((_BYTE *)CurrentThread + 194) & 2) == 0 || !(_BYTE)v9 )
{
LABEL_21:
*((_BYTE *)CurrentThread + 388) = 5;
*((_BYTE *)CurrentThread + 643) = 15;
*((_DWORD *)CurrentThread + 109) = KUSER_SHARED_DATA.TickCount.LowPart;
*((_QWORD *)CurrentThread + 8) = 0i64;
v17 = 0i64;
goto LABEL_22;
}
goto LABEL_91;
}
if( *((_BYTE *)CurrentThread + v9 + 114) )
{
*((_BYTE *)CurrentThread + v9 + 114) = 0;
v17 = 257i64;
goto LABEL_92;
}
if( (_BYTE)v9 && *((_ETHREAD **)CurrentThread + 21) != (_ETHREAD *)((char *)CurrentThread + 168) )
{
*((_BYTE *)CurrentThread + 194) |= 2u;
LABEL_91:
v17 = 192i64;
goto LABEL_92;
}
if( !*((_BYTE *)CurrentThread + 114) )
goto LABEL_21;
*((_BYTE *)CurrentThread + 114) = 0;
v17 = 257i64;
LABEL_92:
KiReleaseThreadLockSafe((INT64)CurrentThread);
KiCheckForThreadDispatch(KeGetCurrentPrcb(), i);
LABEL_22:
if( v17 )
{
*EntryArray = (PLIST_ENTRY)v17;
return v12;
}
if( Queue != *((PKQUEUE *)CurrentThread + 29) )
KiSwitchQueue(CurrentThread, Queue);
*((_BYTE *)CurrentThread + 336) = 3;
*((_BYTE *)CurrentThread + 337) = 4;
v18 = 0;
*((_WORD *)CurrentThread + 169) = 128;
*((_QWORD *)CurrentThread + 44) = Queue;
while( _interlockedbittestandset(&Queue->Header.Lock, 7u) )
{
do
{
++v18;
_mm_pause();
}
while( (Queue->Header.LockNV & 0x80u) != 0 );
}
if( Queue->Header.SignalState )
{
if( Queue->CurrentCount <= Queue->MaximumCount )
{
LODWORD(v27) = KiAttemptFastRemoveQueue(Queue, EntryArray, Count);
if( (_DWORD)v27 )
{
_InterlockedAnd(&Queue->Header.Lock, 0xFFFFFF7F);
goto LABEL_85;
}
}
}
if( (Queue->Header.Signalling & 1) != 0 )
break;
v19 = QuadPart;
if( v63 == 2 )
{
v38 = *((unsigned int *)CurrentThread + 238);
v39 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart
- *((_QWORD *)CurrentThread + 31)
- KUSER_SHARED_DATA.InterruptTimeBias;
v19 = QuadPart;
if( *((_BYTE *)CurrentThread + 391)
&& !*((_DWORD *)CurrentThread + 121)
&& !*((_BYTE *)CurrentThread + 390)
&& !*((_BYTE *)CurrentThread + 192)
&& (_DWORD)v38 )
{
v19 = v38 + QuadPart;
}
}
else
{
if( !v63 )
goto LABEL_30;
if( !QuadPart )
{
LABEL_106:
_InterlockedAnd(&Queue->Header.Lock, 0xFFFFFF7F);
*EntryArray = (PLIST_ENTRY)258;
goto LABEL_107;
}
v39 = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
}
if( v39 > v19 )
goto LABEL_106;
LABEL_30:
_InterlockedDecrement((volatile signed __int32 *)&Queue->CurrentCount);
p_WaitListHead = &Queue->Header.WaitListHead;
v21 = Queue->Header.WaitListHead.Flink;
if( v21->Blink != &Queue->Header.WaitListHead )
goto LABEL_160;
v16->Flink = v21;
*((_QWORD *)CurrentThread + 41) = p_WaitListHead;
v21->Blink = v16;
p_WaitListHead->Flink = v16;
_InterlockedAnd(&Queue->Header.Lock, 0xFFFFFF7F);
*((_BYTE *)CurrentThread + 587) = 1;
v22 = (_LIST_ENTRY *)KiCommitThreadWait((__int64)CurrentThread, (__int64 *)CurrentThread + 40, v63, QuadPart, 0i64);
*((_BYTE *)CurrentThread + 643) = 0;
if( v22 != (_LIST_ENTRY *)256 )
{
*EntryArray = v22;
if( Count > 1
&& (unsigned __int64)&v22[-17].Blink + 7 > 1
&& v22 != (_LIST_ENTRY *)128
&& v22 != (_LIST_ENTRY *)192
&& Queue->Header.SignalState )
{
v41 = KeGetCurrentIrql();
__writecr8(2ui64);
KiAcquireKobjectLockSafe(Queue);
if( Queue->Header.SignalState )
v12 = KiAttemptFastRemoveQueue(Queue, EntryArray + 1, Count - 1) + 1;
_InterlockedAnd(&Queue->Header.Lock, 0xFFFFFF7F);
__writecr8(v41);
}
return v12;
}
i = KeGetCurrentIrql();
__writecr8(2ui64);
}
if( !*((_QWORD *)CurrentThread + 29) )
goto LABEL_159;
v55 = *((_QWORD *)CurrentThread + 65);
v56 = (_ETHREAD **)*((_QWORD *)CurrentThread + 66);
if( *(_ETHREAD **)(v55 + 8) != (_ETHREAD *)((char *)CurrentThread + 520)
|| *v56 != (_ETHREAD *)((char *)CurrentThread + 520) )
{
LABEL_160:
__fastfail(3u);
}
*v56 = (_ETHREAD *)v55;
*(_QWORD *)(v55 + 8) = v56;
*((_QWORD *)CurrentThread + 29) = 0i64;
LABEL_159:
_InterlockedAnd(&Queue->Header.Lock, 0xFFFFFF7F);
*EntryArray = (PLIST_ENTRY)128;
LABEL_107:
LODWORD(v27) = 1;
LABEL_85:
*((_BYTE *)CurrentThread + 643) = 0;
v40 = KeGetCurrentPrcb();
if( *((_QWORD *)v40 + 1441) )
KiProcessThreadWaitList((struct KPRCB *)v40, 1, 0);
KiFastExitThreadWait((__int64)v40, (__int64)CurrentThread, 1);
return v27;
}Referenced by:
IoRemoveIoCompletion
KeRemoveQueue