ExpWorkerFactoryCheckCreate
VOID __stdcall ExpWorkerFactoryCheckCreate(VOID *WorkerFactory, PKLOCK_QUEUE_HANDLE LockHandle, UINT8 DeferredRequest){
_KLOCK_QUEUE_HANDLE *v4;
unsigned int v6;
volatile __int64 *v7;
unsigned __int8 CurrentIrql;
__int64 v9;
_KSPIN_LOCK_QUEUE *Next;
unsigned __int64 OldIrql;
__int64 v12;
unsigned int *v13;
unsigned int v14;
unsigned int v15;
NTSTATUS Thread;
unsigned int v17;
unsigned int v18;
unsigned int v19;
int v20;
char v21;
int v22;
INT64 v23[2];
__int64 v24;
v4 = LockHandle;
*(_OWORD *)v23 = 0i64;
v24 = 0i64;
v6 = 2;
if( !LockHandle )
{
v7 = (volatile __int64 *)*((_QWORD *)WorkerFactory + 2);
v4 = (_KLOCK_QUEUE_HANDLE *)v23;
v23[1] = (INT64)v7;
v23[0] = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LOBYTE(v24) = CurrentIrql;
if( _InterlockedExchange64(v7, (__int64)v23) )
KxWaitForLockOwnerShip((INT64)v23);
}
if( DeferredRequest )
{
v18 = *((_DWORD *)WorkerFactory + 78);
if( (((unsigned __int8)v18 | (unsigned __int8)((v18 | (v18 >> 6)) >> 2)) & 0x30) == 0 && (v18 & 0x100) == 0 )
goto LABEL_40;
}
if( *((_DWORD *)WorkerFactory + 76)
|| *((_DWORD *)WorkerFactory + 72) >= *((_DWORD *)WorkerFactory + 71)
|| (v9 = *((_QWORD *)WorkerFactory + 2), *(_DWORD *)(v9 + 28))
|| (v12 = *(_QWORD *)(v9 + 8), !*(_DWORD *)(v12 + 4)) && !*(_DWORD *)(v9 + 24) )
{
*((_DWORD *)WorkerFactory + 78) &= 0xFFFFCE0F;
_m_prefetchw(v4);
Next = v4->LockQueue.Next;
if( !v4->LockQueue.Next )
{
if( v4 == (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)v4->LockQueue.Lock,
0i64,
(signed __int64)v4) )
{
LABEL_10:
OldIrql = v4->OldIrql;
LABEL_11:
__writecr8(OldIrql);
return;
}
Next = KxWaitForLockChainValid(&v4->LockQueue);
}
v4->LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_10;
}
v13 = (unsigned int *)((char *)WorkerFactory + 312);
if( (!DeferredRequest || (*v13 & 0xC0) != 0x80) && *(_DWORD *)(v12 + 40) >= (unsigned int)KeNumberProcessors_0 )
{
v19 = *v13;
if( (*v13 & 0xC0) != 0 )
{
if( (v19 & 0xC0) != 64 || !DeferredRequest )
goto LABEL_40;
v17 = v19 & 0xFFFFFF3F | 0x80;
*v13 = v17;
}
else
{
v6 = 3;
v17 = v19 & 0xFFFFFF3F | 0x40;
*v13 = v17;
}
goto LABEL_44;
}
if( (!DeferredRequest || (*((_DWORD *)WorkerFactory + 78) & 0x30) != 32)
&& ExpCheckThreadHistory((_EX_WORKER_FACTORY *)WorkerFactory) )
{
v13 = (unsigned int *)((char *)WorkerFactory + 312);
v20 = *((_DWORD *)WorkerFactory + 78);
if( (v20 & 0x30) != 0 )
{
if( (v20 & 0x30) != 16 || !DeferredRequest )
goto LABEL_40;
v17 = v20 & 0xFFFFFFCF | 0x20;
*v13 = v17;
}
else
{
v6 = 3;
v17 = v20 & 0xFFFFFFCF | 0x10;
*v13 = v17;
}
goto LABEL_44;
}
if( !DeferredRequest || (*((_DWORD *)WorkerFactory + 78) & 0x3000) != 0x2000 )
{
v14 = *((_DWORD *)WorkerFactory + 75);
if( v14 )
{
if( *((_DWORD *)WorkerFactory + 72) > v14 )
{
v13 = (unsigned int *)((char *)WorkerFactory + 312);
v22 = *((_DWORD *)WorkerFactory + 78);
if( (v22 & 0x3000) == 0 )
{
v6 = 3;
v17 = v22 & 0xFFFFCFFF | 0x1000;
*v13 = v17;
goto LABEL_44;
}
if( (*((_DWORD *)WorkerFactory + 78) & 0x3000) == 4096 && DeferredRequest )
{
v17 = v22 & 0xFFFFCFFF | 0x2000;
*v13 = v17;
goto LABEL_44;
}
LABEL_40:
KeReleaseInStackQueuedSpinLockFromDpcLevel(v4);
OldIrql = v4->OldIrql;
goto LABEL_11;
}
}
}
v13 = (unsigned int *)((char *)WorkerFactory + 312);
v15 = *((_DWORD *)WorkerFactory + 78);
if( (v15 & 0x200) != 0 )
{
ExpLeaveWorkerFactoryAwayMode((_EX_WORKER_FACTORY *)WorkerFactory);
v15 = *v13;
}
++*((_DWORD *)WorkerFactory + 76);
*v13 = v15 & 0xFFFFCE0F;
KeReleaseInStackQueuedSpinLockFromDpcLevel(v4);
__writecr8(v4->OldIrql);
Thread = ExpWorkerFactoryCreateThread((_EX_WORKER_FACTORY *)WorkerFactory);
if( Thread < 0 )
{
KeAcquireInStackQueuedSpinLock(*((PKSPIN_LOCK *)WorkerFactory + 2), v4);
--*((_DWORD *)WorkerFactory + 76);
if( Thread == -1073741558 || Thread == -1073741814 || Thread == -1073741582 || Thread == -1073741823 )
goto LABEL_40;
*v13 |= 0x100u;
v6 = 1;
v17 = *v13;
LABEL_44:
v21 = 0;
if( (v17 & 8) == 0 )
{
v21 = 1;
*v13 = v17 | 8;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(v4);
__writecr8(v4->OldIrql);
if( v21 )
{
ObfReferenceObjectWithTag(WorkerFactory, 0x746C6644ui64);
RtlpInterlockedPushEntrySList(&xmmword_140CEBEE0, (PSLIST_ENTRY)WorkerFactory);
}
ExpSetWorkerFactoryDeferredCreateTimer(v6);
}
}Referenced by:
ExpWorkerFactoryDeferredThreadCreation
ExpWorkerFactoryManagerThread
NtReleaseWorkerFactoryWorker
NtSetInformationWorkerFactory
NtWaitForWorkViaWorkerFactory