NtSetInformationWorkerFactory
NTSTATUS __stdcall NtSetInformationWorkerFactory(
VOID *WorkerFactoryHandle,
_WORKERFACTORYINFOCLASS WorkerFactoryInformationClass,
VOID *WorkerFactoryInformation,
UINT64 WorkerFactoryInformationLength){
unsigned int v4;
char PreviousMode;
size_t v9;
__int64 v10;
NTSTATUS result;
int Thread;
bool v13;
char v14;
unsigned __int64 *v15;
unsigned __int8 CurrentIrql;
_EX_WORKER_FACTORY *v17;
int v18;
int v19;
int v20;
char v21;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned int v23;
int v24;
unsigned int v25;
unsigned int v26;
unsigned int v27;
_EX_WORKER_FACTORY *v28;
_EX_WORKER_FACTORY v29;
PKSPIN_LOCK v30;
unsigned int v31;
INT64 v32;
PKSPIN_LOCK *v33;
_DWORD *v34;
unsigned int v35;
PKSPIN_LOCK *v36;
VOID *v37;
int v38;
PVOID WorkerFactory;
PKSPIN_LOCK *v40;
size_t Size[2];
_KLOCK_QUEUE_HANDLE LockHandle;
_DWORD *v43;
_EXT_SET_PARAMETERS_V0 Parameters;
__int64 DueTime[20];
v4 = WorkerFactoryInformationLength;
memset(&LockHandle, 0, sizeof(LockHandle));
Parameters = 0i64;
PreviousMode = KeGetCurrentThread()->PreviousMode;
memset(DueTime, 0i64, sizeof(DueTime));
if( WorkerFactoryInformationClass == WorkerFactoryCallbackType )
{
LABEL_2:
v9 = 4;
LABEL_3:
Size[0] = v9;
if( v4 != v9 )
return -1073741820;
if( WorkerFactoryInformationClass == WorkerFactoryCallbackType )
{
if( PreviousMode )
{
if( ((unsigned __int8)WorkerFactoryInformation & 3) != 0 )
ExRaiseDatatypeMisalignment();
if( (unsigned __int64)WorkerFactoryInformation + 4 > 0x7FFFFFFF0000i64
|| (char *)WorkerFactoryInformation + 4 < WorkerFactoryInformation )
{
MEMORY[0x7FFFFFFF0000] = 0;
}
}
LABEL_9:
LODWORD(DueTime[0]) = *(_DWORD *)WorkerFactoryInformation;
}
else
{
switch( WorkerFactoryInformationClass )
{
case WorkerFactoryIdleTimeout:
if( PreviousMode && ((unsigned __int8)WorkerFactoryInformation & 3) != 0 )
ExRaiseDatatypeMisalignment();
DueTime[0] = *(_QWORD *)WorkerFactoryInformation;
break;
case WorkerFactoryBindingCount:
case WorkerFactoryThreadMinimum:
case WorkerFactoryThreadMaximum:
if( !PreviousMode )
goto LABEL_9;
v10 = (__int64)WorkerFactoryInformation;
if( (unsigned __int64)WorkerFactoryInformation >= 0x7FFFFFFF0000i64 )
v10 = 0x7FFFFFFF0000i64;
LODWORD(DueTime[0]) = *(_DWORD *)v10;
break;
default:
__fastfail(0x25u);
}
}
WorkerFactory = 0i64;
result = ObReferenceObjectByHandle(
WorkerFactoryHandle,
4ui64,
ExpWorkerFactoryObjectType,
PreviousMode,
&WorkerFactory,
0i64);
if( result >= 0 )
{
if( WorkerFactoryInformationClass != WorkerFactoryAdjustThreadGoal )
{
Thread = 0;
v13 = 0;
v14 = 1;
v40 = (PKSPIN_LOCK *)WorkerFactory;
v15 = (unsigned __int64 *)*((_QWORD *)WorkerFactory + 2);
LockHandle.LockQueue.Lock = v15;
LockHandle.LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.OldIrql = CurrentIrql;
if( _InterlockedExchange64((volatile __int64 *)v15, (__int64)&LockHandle) )
KxWaitForLockOwnerShip((INT64)&LockHandle);
if( WorkerFactoryInformationClass != WorkerFactoryCallbackType )
{
switch( WorkerFactoryInformationClass )
{
case WorkerFactoryIdleTimeout:
v32 = DueTime[0];
if( DueTime[0] >= 0 )
{
Thread = -1073741811;
v17 = (_EX_WORKER_FACTORY *)WorkerFactory;
}
else
{
if( DueTime[0] > -10000000 )
{
v32 = -10000000i64;
DueTime[0] = -10000000i64;
}
else if( DueTime[0] < -6000000000i64 )
{
v32 = -6000000000i64;
DueTime[0] = -6000000000i64;
}
v17 = (_EX_WORKER_FACTORY *)WorkerFactory;
*((_QWORD *)WorkerFactory + 14) = v32;
Parameters.NoWakeTolerance = -1i64;
KeSetTimer2((INT64)(v17 + 82), v32, -v32, (INT64)&Parameters);
}
goto LABEL_35;
case WorkerFactoryBindingCount:
v17 = (_EX_WORKER_FACTORY *)WorkerFactory;
v23 = *((_DWORD *)WorkerFactory + 77);
if( SLODWORD(DueTime[0]) < 0 )
{
if( v23 > -LODWORD(DueTime[0]) )
{
v24 = v23 + LODWORD(DueTime[0]);
*((_DWORD *)WorkerFactory + 77) = v23 + LODWORD(DueTime[0]);
}
else
{
*((_DWORD *)WorkerFactory + 77) = 0;
v24 = 0;
}
}
else
{
v24 = v23 + LODWORD(DueTime[0]);
if( v23 >= v23 + LODWORD(DueTime[0]) )
v24 = -1;
*((_DWORD *)WorkerFactory + 77) = v24;
}
if( v23 )
{
if( !v24 && (v17[78] & 0x200) != 0 )
ExpLeaveWorkerFactoryAwayMode(v17);
}
else if( v24 && ExpTryEnterWorkerFactoryAwayMode(v17) )
{
ExpWorkerFactoryCheckCreate(v17, &LockHandle, 0);
v14 = 0;
}
goto LABEL_35;
case WorkerFactoryThreadMinimum:
v33 = v40;
v17 = (_EX_WORKER_FACTORY *)WorkerFactory;
if( *((_BYTE *)v40[2] + 33) )
{
Thread = 128;
}
else
{
v34 = (char *)WorkerFactory + 280;
v13 = 0;
v35 = DueTime[0];
if( LODWORD(DueTime[0]) > *((_DWORD *)WorkerFactory + 70) )
v13 = 1;
*v34 = DueTime[0];
if( v17[71] < v35 )
v17[71] = v35;
if( v13 )
{
v13 = 0;
if( (v17[78] & 0x200) != 0 )
ExpLeaveWorkerFactoryAwayMode(v17);
*(_QWORD *)Size = v17 + 74;
v43 = v17 + 72;
if( (unsigned int)(v17[74] + v17[72]) < *v34 )
{
v36 = (PKSPIN_LOCK *)(v17 + 76);
v40 = (PKSPIN_LOCK *)(v17 + 76);
while( 1 )
{
++*(_DWORD *)v36;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
Thread = ExpWorkerFactoryCreateThread(v17);
KeAcquireInStackQueuedSpinLock(v33[2], &LockHandle);
if( Thread < 0 )
break;
v36 = v40;
if( (unsigned int)(**(_DWORD **)Size + *v43) >= *v34 )
goto LABEL_35;
}
--*(_DWORD *)v40;
}
}
}
goto LABEL_35;
case WorkerFactoryThreadMaximum:
v30 = v40[2];
v17 = (_EX_WORKER_FACTORY *)WorkerFactory;
if( *((_BYTE *)v30 + 33) )
{
Thread = 128;
goto LABEL_35;
}
v21 = 1;
v31 = DueTime[0];
if( LODWORD(DueTime[0])
&& (!*((_DWORD *)WorkerFactory + 71) && *((_DWORD *)v30 + 6) || *(int *)(v30[1] + 4) > 0) )
{
v13 = 1;
}
*((_DWORD *)WorkerFactory + 71) = DueTime[0];
if( v31 < v17[70] )
v17[70] = v31;
break;
default:
__fastfail(0x25u);
}
LABEL_36:
if( v13 )
{
v25 = v17[72];
v26 = v25 + v17[74];
v40 = (PKSPIN_LOCK *)(v17 + 4);
if( *(_BYTE *)(*((_QWORD *)v17 + 2) + 33i64) )
{
Thread = 128;
}
else
{
v27 = v17[71];
if( v25 >= v27 )
{
if( !v21 )
Thread = -1073741527;
}
else
{
v28 = v17 + 76;
v29 = v17[76];
if( v29 || v26 >= v27 )
goto LABEL_68;
if( (v17[78] & 0x200) != 0 )
{
ExpLeaveWorkerFactoryAwayMode(v17);
v29 = *v28;
}
*v28 = v29 + 1;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v14 = 0;
Thread = ExpWorkerFactoryCreateThread(v17);
if( Thread < 0 )
{
v14 = 1;
KeAcquireInStackQueuedSpinLock(*v40, &LockHandle);
--*v28;
if( v21 )
LABEL_68:
Thread = 0;
}
}
}
}
if( !v14 )
goto LABEL_41;
_m_prefetchw(&LockHandle);
Next = LockHandle.LockQueue.Next;
if( !LockHandle.LockQueue.Next )
{
if( (_KLOCK_QUEUE_HANDLE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockHandle.LockQueue.Lock,
0i64,
(signed __int64)&LockHandle) == &LockHandle )
{
LABEL_40:
__writecr8(LockHandle.OldIrql);
v17 = (_EX_WORKER_FACTORY *)WorkerFactory;
LABEL_41:
ObfDereferenceObjectWithTag(v17, 0x746C6644ui64);
return Thread;
}
Next = KxWaitForLockChainValid(&LockHandle.LockQueue);
}
LockHandle.LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_40;
}
v17 = (_EX_WORKER_FACTORY *)WorkerFactory;
if( !LODWORD(DueTime[0]) )
{
v20 = *((_DWORD *)WorkerFactory + 72);
if( v20 == *((_DWORD *)WorkerFactory + 73) )
Thread = -1073741823;
else
*((_DWORD *)WorkerFactory + 72) = v20 + 1;
goto LABEL_35;
}
if( LODWORD(DueTime[0]) == 1 )
goto LABEL_32;
if( LODWORD(DueTime[0]) != 2 )
{
if( LODWORD(DueTime[0]) == 3 )
{
if( *((_DWORD *)WorkerFactory + 72) )
{
ExpRemoveCurrentThreadFromThreadHistory((_EX_WORKER_FACTORY *)WorkerFactory);
--v17[72];
--v17[73];
v13 = v17[72] == 0;
}
else
{
Thread = -1073741823;
}
}
else
{
Thread = -1073741811;
}
goto LABEL_35;
}
v18 = *((_DWORD *)WorkerFactory + 72);
if( !v18 )
{
Thread = -1073741823;
goto LABEL_35;
}
v19 = v18 - 1;
*((_DWORD *)WorkerFactory + 72) = v19;
if( !v19 )
LABEL_32:
v13 = 1;
LABEL_35:
v21 = 0;
goto LABEL_36;
}
v37 = WorkerFactory;
v38 = DueTime[0];
if( !LODWORD(DueTime[0]) )
{
v38 = KeNumberProcessors_0;
v37 = WorkerFactory;
}
*(_DWORD *)(*(_QWORD *)(*((_QWORD *)WorkerFactory + 2) + 8i64) + 44i64) = v38;
ObfDereferenceObjectWithTag(v37, 0x746C6644ui64);
return 0;
}
}
else
{
switch( WorkerFactoryInformationClass )
{
case WorkerFactoryIdleTimeout:
v9 = 8;
goto LABEL_3;
case WorkerFactoryBindingCount:
case WorkerFactoryThreadMinimum:
case WorkerFactoryThreadMaximum:
case WorkerFactoryAdjustThreadGoal:
case WorkerFactoryThreadBasePriority:
case WorkerFactoryTimeoutWaiters:
case WorkerFactoryFlags:
case WorkerFactoryThreadSoftMaximum:
goto LABEL_2;
case WorkerFactoryPaused:
result = -1073741822;
break;
case WorkerFactoryStackInformation:
v9 = 16;
goto LABEL_3;
case MaxWorkerFactoryInfoClass:
if( v4 >= 0xA0 )
v9 = 160;
else
v9 = v4 + (v4 & 7);
goto LABEL_3;
default:
result = -1073741821;
break;
}
}
return result;
}Referenced by:
No references.