NtReleaseWorkerFactoryWorker
NTSTATUS __stdcall NtReleaseWorkerFactoryWorker(PVOID WorkerFactoryHandle){
NTSTATUS result;
_QWORD *v2;
unsigned __int64 *v3;
unsigned __int8 CurrentIrql;
KSPIN_LOCK_QUEUE *v5;
__int64 v6;
char v7;
int v8;
__int64 v9;
NTSTATUS v10;
_KSPIN_LOCK_QUEUE *volatile Next;
__int64 v12;
INT64 v13;
KQUEUE *v14;
_LIST_ENTRY *p_WaitListHead;
UINT8 v16;
struct _KPRCB *CurrentPrcb;
__int64 v18;
PVOID v19;
int SignalState;
KQUEUE **Blink;
BYTE *MiniCompletionPacket;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v24;
PVOID Object;
v24 = 0i64;
LockQueue = 0i64;
Object = 0i64;
result = ObReferenceObjectByHandle(
WorkerFactoryHandle,
1u,
ExpWorkerFactoryObjectType,
*((_BYTE *)KeGetCurrentThread() + 562),
&Object,
0i64);
if( result < 0 )
return result;
v2 = Object;
v3 = (unsigned __int64 *)*((_QWORD *)Object + 2);
LockQueue.Lock = v3;
LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LOBYTE(v24) = CurrentIrql;
v5 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)v3, (__int64)&LockQueue);
if( v5 )
KxWaitForLockOwnerShip(&LockQueue, v5);
v6 = v2[2];
v7 = 0;
if( *(_BYTE *)(v6 + 33) )
{
v10 = 128;
}
else
{
v8 = *(_DWORD *)(v6 + 24);
if( v8 == -1 )
{
v10 = -1073741823;
}
else
{
*(_DWORD *)(v6 + 24) = v8 + 1;
v9 = v2[2];
if( !*(_BYTE *)(v9 + 32) )
{
*(_BYTE *)(v9 + 32) = 1;
v7 = 1;
}
v10 = 0;
if( v7 && (*((_DWORD *)Object + 78) & 0x200) != 0 )
ExpLeaveWorkerFactoryAwayMode((CHAR *)Object);
}
}
_m_prefetchw(&LockQueue);
Next = LockQueue.Next;
if( LockQueue.Next )
goto LABEL_30;
if( (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.Lock,
0i64,
(signed __int64)&LockQueue) != &LockQueue )
{
Next = KxWaitForLockChainValid(&LockQueue);
LABEL_30:
LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
}
__writecr8((unsigned __int8)v24);
if( v7 )
{
v12 = v2[2];
v13 = *(_QWORD *)(v12 + 16);
v14 = *(KQUEUE **)(v12 + 8);
if( v13 )
{
*(_QWORD *)(v13 + 24) = 0i64;
p_WaitListHead = &v14->Header.WaitListHead;
*(_QWORD *)(v13 + 32) = 0i64;
*(_DWORD *)(v13 + 40) = 0;
*(_QWORD *)(v13 + 48) = 0i64;
v16 = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
v18 = *((_QWORD *)CurrentPrcb + 1);
KiAcquireKobjectLockSafe(v14);
if( p_WaitListHead->Flink == p_WaitListHead
|| v14->CurrentCount >= v14->MaximumCount
|| *(KQUEUE **)(v18 + 232) == v14 && *(_BYTE *)(v18 + 643) == 15
|| !KiWakeQueueWaiter(CurrentPrcb, v14, v13) )
{
SignalState = v14->Header.SignalState;
v14->Header.SignalState = SignalState + 1;
Blink = (KQUEUE **)v14->EntryListHead.Blink;
if( *Blink != (KQUEUE *)&v14->EntryListHead )
__fastfail(3u);
*(_QWORD *)v13 = &v14->EntryListHead;
*(_QWORD *)(v13 + 8) = Blink;
*Blink = (KQUEUE *)v13;
v14->EntryListHead.Blink = (_LIST_ENTRY *)v13;
if( !SignalState && p_WaitListHead->Flink != p_WaitListHead )
KiWakeOtherQueueWaiters(CurrentPrcb, v14);
}
_InterlockedAnd(&v14->Header.Lock, 0xFFFFFF7F);
KiExitDispatcher(CurrentPrcb, 0i64, AdjustUnwait, 0i64, v16);
}
else
{
MiniCompletionPacket = IopAllocateMiniCompletionPacket(1, 0);
if( MiniCompletionPacket )
{
*((_QWORD *)MiniCompletionPacket + 3) = 0i64;
*((_QWORD *)MiniCompletionPacket + 4) = 0i64;
*((_DWORD *)MiniCompletionPacket + 10) = 0;
*((_QWORD *)MiniCompletionPacket + 6) = 0i64;
KeInsertQueueEx(v14, (LIST_ENTRY *)MiniCompletionPacket, 0i64, 0);
}
}
v19 = Object;
ExpWorkerFactoryCheckCreate((CHAR *)Object, 0i64, 0i64);
}
else
{
v19 = Object;
}
ObfDereferenceObjectWithTag(v19, 0x746C6644ui64);
return v10;
}Referenced by:
No references.