ExpWorkerFactoryCheckCreate
VOID __fastcall ExpWorkerFactoryCheckCreate(CHAR *ListEntry, KLOCK_QUEUE_HANDLE *LockHandle, UINT8 *a3){
char v3;
KLOCK_QUEUE_HANDLE *p_LockQueue;
unsigned int v6;
unsigned __int64 *v7;
unsigned __int8 CurrentIrql;
KSPIN_LOCK_QUEUE *v9;
__int64 v10;
_KSPIN_LOCK_QUEUE *Next;
unsigned __int64 OldIrql;
__int64 v13;
CHAR *v14;
unsigned int v15;
unsigned int v16;
int Thread;
unsigned int v18;
unsigned int v19;
unsigned int v20;
int v21;
char v22;
int v23;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v25;
v3 = (char)a3;
p_LockQueue = LockHandle;
LockQueue = 0i64;
v25 = 0i64;
v6 = 2;
if( !LockHandle )
{
v7 = (unsigned __int64 *)*((_QWORD *)ListEntry + 2);
p_LockQueue = (KLOCK_QUEUE_HANDLE *)&LockQueue;
LockQueue.Lock = v7;
LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LOBYTE(v25) = CurrentIrql;
v9 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)v7, (__int64)&LockQueue);
if( v9 )
KxWaitForLockOwnerShip(&LockQueue, v9);
}
if( v3 )
{
v19 = *((_DWORD *)ListEntry + 78);
if( (((unsigned __int8)v19 | (unsigned __int8)((v19 | (v19 >> 6)) >> 2)) & 0x30) == 0 && (v19 & 0x100) == 0 )
goto LABEL_40;
}
if( *((_DWORD *)ListEntry + 76)
|| *((_DWORD *)ListEntry + 72) >= *((_DWORD *)ListEntry + 71)
|| (v10 = *((_QWORD *)ListEntry + 2), *(_DWORD *)(v10 + 28))
|| (v13 = *(_QWORD *)(v10 + 8), !*(_DWORD *)(v13 + 4)) && !*(_DWORD *)(v10 + 24) )
{
*((_DWORD *)ListEntry + 78) &= 0xFFFFCE0F;
_m_prefetchw(p_LockQueue);
Next = p_LockQueue->LockQueue.Next;
if( !p_LockQueue->LockQueue.Next )
{
if( p_LockQueue == (KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)p_LockQueue->LockQueue.Lock,
0i64,
(signed __int64)p_LockQueue) )
{
LABEL_10:
OldIrql = p_LockQueue->OldIrql;
LABEL_11:
__writecr8(OldIrql);
return;
}
Next = KxWaitForLockChainValid(&p_LockQueue->LockQueue);
}
p_LockQueue->LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_10;
}
v14 = ListEntry + 312;
if( (!v3 || (*(_DWORD *)v14 & 0xC0) != 0x80) && *(_DWORD *)(v13 + 40) >= (unsigned int)KeNumberProcessors_0 )
{
v20 = *(_DWORD *)v14;
if( (*(_DWORD *)v14 & 0xC0) != 0 )
{
if( (v20 & 0xC0) != 64 || !v3 )
goto LABEL_40;
v18 = v20 & 0xFFFFFF3F | 0x80;
*(_DWORD *)v14 = v18;
}
else
{
v6 = 3;
v18 = v20 & 0xFFFFFF3F | 0x40;
*(_DWORD *)v14 = v18;
}
goto LABEL_44;
}
if( (!v3 || (*((_DWORD *)ListEntry + 78) & 0x30) != 32) && ExpCheckThreadHistory((UINT64 *)ListEntry) )
{
v14 = ListEntry + 312;
v21 = *((_DWORD *)ListEntry + 78);
if( (v21 & 0x30) != 0 )
{
if( (v21 & 0x30) != 16 || !v3 )
goto LABEL_40;
v18 = v21 & 0xFFFFFFCF | 0x20;
*(_DWORD *)v14 = v18;
}
else
{
v6 = 3;
v18 = v21 & 0xFFFFFFCF | 0x10;
*(_DWORD *)v14 = v18;
}
goto LABEL_44;
}
if( !v3 || (*((_DWORD *)ListEntry + 78) & 0x3000) != 0x2000 )
{
v15 = *((_DWORD *)ListEntry + 75);
if( v15 )
{
if( *((_DWORD *)ListEntry + 72) > v15 )
{
v14 = ListEntry + 312;
v23 = *((_DWORD *)ListEntry + 78);
if( (v23 & 0x3000) == 0 )
{
v6 = 3;
v18 = v23 & 0xFFFFCFFF | 0x1000;
*(_DWORD *)v14 = v18;
goto LABEL_44;
}
if( (*((_DWORD *)ListEntry + 78) & 0x3000) == 4096 && v3 )
{
v18 = v23 & 0xFFFFCFFF | 0x2000;
*(_DWORD *)v14 = v18;
goto LABEL_44;
}
LABEL_40:
KeReleaseInStackQueuedSpinLockFromDpcLevel(p_LockQueue);
OldIrql = p_LockQueue->OldIrql;
goto LABEL_11;
}
}
}
v14 = ListEntry + 312;
v16 = *((_DWORD *)ListEntry + 78);
if( (v16 & 0x200) != 0 )
{
ExpLeaveWorkerFactoryAwayMode(ListEntry);
v16 = *(_DWORD *)v14;
}
++*((_DWORD *)ListEntry + 76);
*(_DWORD *)v14 = v16 & 0xFFFFCE0F;
KeReleaseInStackQueuedSpinLockFromDpcLevel(p_LockQueue);
__writecr8(p_LockQueue->OldIrql);
Thread = ExpWorkerFactoryCreateThread((INT64)ListEntry);
if( Thread < 0 )
{
KeAcquireInStackQueuedSpinLock(*((UINT64 **)ListEntry + 2), p_LockQueue);
--*((_DWORD *)ListEntry + 76);
if( Thread == -1073741558 || Thread == -1073741814 || Thread == -1073741582 || Thread == -1073741823 )
goto LABEL_40;
*(_DWORD *)v14 |= 0x100u;
v6 = 1;
v18 = *(_DWORD *)v14;
LABEL_44:
v22 = 0;
if( (v18 & 8) == 0 )
{
v22 = 1;
*(_DWORD *)v14 = v18 | 8;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(p_LockQueue);
__writecr8(p_LockQueue->OldIrql);
if( v22 )
{
ObfReferenceObjectWithTag(ListEntry, 0x746C6644u);
RtlpInterlockedPushEntrySList((PSLIST_HEADER)ExpWorkerFactoryThreadCreationList, (PSLIST_ENTRY)ListEntry);
}
ExpSetWorkerFactoryDeferredCreateTimer(v6);
}
}Referenced by:
ExpWorkerFactoryDeferredThreadCreation
ExpWorkerFactoryManagerThread
NtReleaseWorkerFactoryWorker
NtSetInformationWorkerFactory
NtWaitForWorkViaWorkerFactory