NtSetInformationWorkerFactory
NTSTATUS __stdcall NtSetInformationWorkerFactory(
PVOID Handle,
INT64 INT64,
UINT64 WorkerFactoryInformationClass,
PVOID WorkerFactoryInformation,
UINT64 WorkerFactoryInformationLength){
unsigned int v5;
int v7;
KPROCESSOR_MODE v9;
int v10;
UINT64 v11;
NTSTATUS result;
NTSTATUS Thread;
bool v14;
char v15;
unsigned __int64 *v16;
unsigned __int8 CurrentIrql;
KSPIN_LOCK_QUEUE *v18;
char *v19;
int v20;
int v21;
int v22;
char v23;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned int v25;
int v26;
unsigned int v27;
unsigned int v28;
unsigned int v29;
int *v30;
int v31;
UINT64 *v32;
unsigned int v33;
INT64 v34;
UINT64 **v35;
_DWORD *v36;
unsigned int v37;
UINT64 **v38;
PVOID v39;
int v40;
PVOID Object;
UINT64 **v42;
size_t Size;
struct _KLOCK_QUEUE_HANDLE LockHandle;
_DWORD *v45;
_EXT_SET_PARAMETERS_V0 Parameters;
__int128 Src[10];
v5 = (unsigned int)WorkerFactoryInformation;
v7 = INT64;
memset(&LockHandle, 0, sizeof(LockHandle));
Parameters = 0i64;
v9 = *((_BYTE *)KeGetCurrentThread() + 562);
memset((INT64)Src, 0i64);
if( v7 == 9 )
{
LABEL_2:
v10 = 4;
LABEL_3:
LODWORD(Size) = v10;
if( v5 != v10 )
return -1073741820;
if( v7 == 9 )
{
if( v9 )
{
if( (WorkerFactoryInformationClass & 3) != 0 )
ExRaiseDatatypeMisalignment();
if( WorkerFactoryInformationClass + 4 > 0x7FFFFFFF0000i64
|| WorkerFactoryInformationClass + 4 < WorkerFactoryInformationClass )
{
MEMORY[0x7FFFFFFF0000] = 0;
}
}
LABEL_9:
LODWORD(Src[0]) = *(_DWORD *)WorkerFactoryInformationClass;
}
else
{
switch( v7 )
{
case 2:
if( v9 && (WorkerFactoryInformationClass & 3) != 0 )
ExRaiseDatatypeMisalignment();
*(_QWORD *)&Src[0] = *(_QWORD *)WorkerFactoryInformationClass;
break;
case 3:
case 4:
case 5:
if( !v9 )
goto LABEL_9;
v11 = WorkerFactoryInformationClass;
if( WorkerFactoryInformationClass >= 0x7FFFFFFF0000i64 )
v11 = 0x7FFFFFFF0000i64;
LODWORD(Src[0]) = *(_DWORD *)v11;
break;
default:
__fastfail(0x25u);
}
}
Object = 0i64;
result = ObReferenceObjectByHandle(Handle, 4u, ExpWorkerFactoryObjectType, v9, &Object, 0i64);
if( result >= 0 )
{
if( v7 != 8 )
{
Thread = 0;
v14 = 0;
v15 = 1;
v42 = (UINT64 **)Object;
v16 = (unsigned __int64 *)*((_QWORD *)Object + 2);
LockHandle.LockQueue.Lock = v16;
LockHandle.LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.OldIrql = CurrentIrql;
v18 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)v16, (__int64)&LockHandle);
if( v18 )
KxWaitForLockOwnerShip(&LockHandle.LockQueue, v18);
if( v7 != 9 )
{
switch( v7 )
{
case 2:
v34 = *(_QWORD *)&Src[0];
if( *(__int64 *)&Src[0] >= 0 )
{
Thread = -1073741811;
v19 = (char *)Object;
}
else
{
if( *(__int64 *)&Src[0] > -10000000 )
{
v34 = -10000000i64;
*(_QWORD *)&Src[0] = -10000000i64;
}
else if( *(__int64 *)&Src[0] < -6000000000i64 )
{
v34 = -6000000000i64;
*(_QWORD *)&Src[0] = -6000000000i64;
}
v19 = (char *)Object;
*((_QWORD *)Object + 14) = v34;
Parameters.NoWakeTolerance = -1i64;
KeSetTimer2((_KTIMER2 *)(v19 + 328), v34, -v34, &Parameters);
}
goto LABEL_35;
case 3:
v19 = (char *)Object;
v25 = *((_DWORD *)Object + 77);
if( SLODWORD(Src[0]) < 0 )
{
if( v25 > -LODWORD(Src[0]) )
{
v26 = v25 + LODWORD(Src[0]);
*((_DWORD *)Object + 77) = v25 + LODWORD(Src[0]);
}
else
{
*((_DWORD *)Object + 77) = 0;
v26 = 0;
}
}
else
{
v26 = v25 + LODWORD(Src[0]);
if( v25 >= v25 + LODWORD(Src[0]) )
v26 = -1;
*((_DWORD *)Object + 77) = v26;
}
if( v25 )
{
if( !v26 && (*((_DWORD *)v19 + 78) & 0x200) != 0 )
ExpLeaveWorkerFactoryAwayMode(v19);
}
else if( v26 && ExpTryEnterWorkerFactoryAwayMode(v19) )
{
ExpWorkerFactoryCheckCreate(v19, &LockHandle, 0i64);
v15 = 0;
}
goto LABEL_35;
case 4:
v35 = v42;
v19 = (char *)Object;
if( *((_BYTE *)v42[2] + 33) )
{
Thread = 128;
}
else
{
v36 = (char *)Object + 280;
v14 = 0;
v37 = Src[0];
if( LODWORD(Src[0]) > *((_DWORD *)Object + 70) )
v14 = 1;
*v36 = Src[0];
if( *((_DWORD *)v19 + 71) < v37 )
*((_DWORD *)v19 + 71) = v37;
if( v14 )
{
v14 = 0;
if( (*((_DWORD *)v19 + 78) & 0x200) != 0 )
ExpLeaveWorkerFactoryAwayMode(v19);
Size = (size_t)(v19 + 296);
v45 = v19 + 288;
if( (unsigned int)(*((_DWORD *)v19 + 74) + *((_DWORD *)v19 + 72)) < *v36 )
{
v38 = (UINT64 **)(v19 + 304);
v42 = (UINT64 **)(v19 + 304);
while( 1 )
{
++*(_DWORD *)v38;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
Thread = ExpWorkerFactoryCreateThread((INT64)v19);
KeAcquireInStackQueuedSpinLock(v35[2], &LockHandle);
if( Thread < 0 )
break;
v38 = v42;
if( (unsigned int)(*(_DWORD *)Size + *v45) >= *v36 )
goto LABEL_35;
}
--*(_DWORD *)v42;
}
}
}
goto LABEL_35;
case 5:
v32 = v42[2];
v19 = (char *)Object;
if( *((_BYTE *)v32 + 33) )
{
Thread = 128;
goto LABEL_35;
}
v23 = 1;
v33 = Src[0];
if( LODWORD(Src[0]) && (!*((_DWORD *)Object + 71) && *((_DWORD *)v32 + 6) || *(int *)(v32[1] + 4) > 0) )
v14 = 1;
*((_DWORD *)Object + 71) = Src[0];
if( v33 < *((_DWORD *)v19 + 70) )
*((_DWORD *)v19 + 70) = v33;
break;
default:
__fastfail(0x25u);
}
LABEL_36:
if( v14 )
{
v27 = *((_DWORD *)v19 + 72);
v28 = v27 + *((_DWORD *)v19 + 74);
v42 = (UINT64 **)(v19 + 16);
if( *(_BYTE *)(*((_QWORD *)v19 + 2) + 33i64) )
{
Thread = 128;
}
else
{
v29 = *((_DWORD *)v19 + 71);
if( v27 >= v29 )
{
if( !v23 )
Thread = -1073741527;
}
else
{
v30 = (int *)(v19 + 304);
v31 = *((_DWORD *)v19 + 76);
if( v31 || v28 >= v29 )
goto LABEL_68;
if( (*((_DWORD *)v19 + 78) & 0x200) != 0 )
{
ExpLeaveWorkerFactoryAwayMode(v19);
v31 = *v30;
}
*v30 = v31 + 1;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v15 = 0;
Thread = ExpWorkerFactoryCreateThread((INT64)v19);
if( Thread < 0 )
{
v15 = 1;
KeAcquireInStackQueuedSpinLock(*v42, &LockHandle);
--*v30;
if( v23 )
LABEL_68:
Thread = 0;
}
}
}
}
if( !v15 )
goto LABEL_41;
_m_prefetchw(&LockHandle);
Next = LockHandle.LockQueue.Next;
if( !LockHandle.LockQueue.Next )
{
if( (struct _KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockHandle.LockQueue.Lock,
0i64,
(signed __int64)&LockHandle) == &LockHandle )
{
LABEL_40:
__writecr8(LockHandle.OldIrql);
v19 = (char *)Object;
LABEL_41:
ObfDereferenceObjectWithTag(v19, 0x746C6644ui64);
return Thread;
}
Next = KxWaitForLockChainValid(&LockHandle.LockQueue);
}
LockHandle.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_40;
}
v19 = (char *)Object;
if( !LODWORD(Src[0]) )
{
v22 = *((_DWORD *)Object + 72);
if( v22 == *((_DWORD *)Object + 73) )
Thread = -1073741823;
else
*((_DWORD *)Object + 72) = v22 + 1;
goto LABEL_35;
}
if( LODWORD(Src[0]) == 1 )
goto LABEL_32;
if( LODWORD(Src[0]) != 2 )
{
if( LODWORD(Src[0]) == 3 )
{
if( *((_DWORD *)Object + 72) )
{
ExpRemoveCurrentThreadFromThreadHistory((INT64)Object);
--*((_DWORD *)v19 + 72);
--*((_DWORD *)v19 + 73);
v14 = *((_DWORD *)v19 + 72) == 0;
}
else
{
Thread = -1073741823;
}
}
else
{
Thread = -1073741811;
}
goto LABEL_35;
}
v20 = *((_DWORD *)Object + 72);
if( !v20 )
{
Thread = -1073741823;
goto LABEL_35;
}
v21 = v20 - 1;
*((_DWORD *)Object + 72) = v21;
if( !v21 )
LABEL_32:
v14 = 1;
LABEL_35:
v23 = 0;
goto LABEL_36;
}
v39 = Object;
v40 = Src[0];
if( !LODWORD(Src[0]) )
{
v40 = KeNumberProcessors_0;
v39 = Object;
}
*(_DWORD *)(*(_QWORD *)(*((_QWORD *)Object + 2) + 8i64) + 44i64) = v40;
ObfDereferenceObjectWithTag(v39, 0x746C6644ui64);
return 0;
}
}
else
{
switch( v7 )
{
case 2:
v10 = 8;
goto LABEL_3;
case 3:
case 4:
case 5:
case 8:
case 11:
case 12:
case 13:
case 14:
goto LABEL_2;
case 6:
result = -1073741822;
break;
case 10:
v10 = 16;
goto LABEL_3;
case 15:
if( v5 >= 0xA0 )
v10 = 160;
else
v10 = v5 + (v5 & 7);
goto LABEL_3;
default:
result = -1073741821;
break;
}
}
return result;
}Referenced by:
No references.