NtReleaseWorkerFactoryWorker
NTSTATUS __stdcall NtReleaseWorkerFactoryWorker(VOID *WorkerFactoryHandle){
NTSTATUS result;
_QWORD *v2;
unsigned __int64 *v3;
unsigned __int8 CurrentIrql;
__int64 v5;
char v6;
int v7;
__int64 v8;
NTSTATUS v9;
_KSPIN_LOCK_QUEUE *volatile Next;
__int64 v11;
INT64 v12;
__int64 v13;
_QWORD *v14;
UINT8 v15;
struct _KPRCB *CurrentPrcb;
_ETHREAD *CurrentThread;
char v18;
VOID *v19;
int v20;
INT64 *v21;
_IOP_MINI_COMPLETION_PACKET *MiniCompletionPacket;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v24;
PVOID WorkerFactory;
v24 = 0i64;
LockQueue = 0i64;
WorkerFactory = 0i64;
result = ObReferenceObjectByHandle(
WorkerFactoryHandle,
1ui64,
ExpWorkerFactoryObjectType,
KeGetCurrentThread()->PreviousMode,
&WorkerFactory,
0i64);
if( result < 0 )
return result;
v2 = WorkerFactory;
v3 = (unsigned __int64 *)*((_QWORD *)WorkerFactory + 2);
LockQueue.Lock = v3;
LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LOBYTE(v24) = CurrentIrql;
if( _InterlockedExchange64((volatile __int64 *)v3, (__int64)&LockQueue) )
KxWaitForLockOwnerShip((INT64)&LockQueue);
v5 = v2[2];
v6 = 0;
if( *(_BYTE *)(v5 + 33) )
{
v9 = 128;
}
else
{
v7 = *(_DWORD *)(v5 + 24);
if( v7 == -1 )
{
v9 = -1073741823;
}
else
{
*(_DWORD *)(v5 + 24) = v7 + 1;
v8 = v2[2];
if( !*(_BYTE *)(v8 + 32) )
{
*(_BYTE *)(v8 + 32) = 1;
v6 = 1;
}
v9 = 0;
if( v6 && (*((_DWORD *)WorkerFactory + 78) & 0x200) != 0 )
ExpLeaveWorkerFactoryAwayMode((_EX_WORKER_FACTORY *)WorkerFactory);
}
}
_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( v6 )
{
v11 = v2[2];
v12 = *(_QWORD *)(v11 + 16);
v13 = *(_QWORD *)(v11 + 8);
if( v12 )
{
*(_QWORD *)(v12 + 24) = 0i64;
v14 = (_QWORD *)(v13 + 8);
*(_QWORD *)(v12 + 32) = 0i64;
*(_DWORD *)(v12 + 40) = 0;
*(_QWORD *)(v12 + 48) = 0i64;
v15 = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
CurrentThread = CurrentPrcb->CurrentThread;
KiAcquireKobjectLockSafe((VOID *)v13);
if( (_QWORD *)*v14 == v14
|| *(_DWORD *)(v13 + 40) >= *(_DWORD *)(v13 + 44)
|| CurrentThread->Tcb.Queue == (_DISPATCHER_HEADER *volatile)v13 && CurrentThread->Tcb.WaitReason == 15
|| (KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)v13, v12), !v18) )
{
v20 = *(_DWORD *)(v13 + 4);
*(_DWORD *)(v13 + 4) = v20 + 1;
v21 = *(INT64 **)(v13 + 32);
if( *v21 != v13 + 24 )
__fastfail(3u);
*(_QWORD *)v12 = v13 + 24;
*(_QWORD *)(v12 + 8) = v21;
*v21 = v12;
*(_QWORD *)(v13 + 32) = v12;
if( !v20 && (_QWORD *)*v14 != v14 )
KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)v13);
}
_InterlockedAnd((volatile signed __int32 *)v13, 0xFFFFFF7F);
KiExitDispatcher(CurrentPrcb, 0i64, AdjustUnwait, 0i64, v15);
}
else
{
MiniCompletionPacket = IopAllocateMiniCompletionPacket(1u, 0);
if( MiniCompletionPacket )
{
*((_QWORD *)MiniCompletionPacket + 3) = 0i64;
*((_QWORD *)MiniCompletionPacket + 4) = 0i64;
MiniCompletionPacket[10] = 0;
*((_QWORD *)MiniCompletionPacket + 6) = 0i64;
KeInsertQueueEx((_KQUEUE *)v13, (_LIST_ENTRY *)MiniCompletionPacket, 0i64, 0);
}
}
v19 = WorkerFactory;
ExpWorkerFactoryCheckCreate(WorkerFactory, 0i64, 0);
}
else
{
v19 = WorkerFactory;
}
ObfDereferenceObjectWithTag(v19, 0x746C6644ui64);
return v9;
}Referenced by:
No references.