KeStartThread
NTSTATUS __fastcall KeStartThread(_ETHREAD *Thread, _GROUP_AFFINITY *GroupAffinity, UINT64 *a3){
_GROUP_AFFINITY *p_Affinity;
_KNODE *v6;
unsigned __int16 ThreadSeed;
_ETHREAD *CurrentThread;
_EPROCESS *Process;
UINT16 v10;
UINT64 *v11;
char BasePriority;
__int64 v13;
unsigned int v14;
_LIST_ENTRY *p_ThreadListHead;
_KPRCB *v16;
int QuantumReset;
int v18;
unsigned __int64 v19;
_LIST_ENTRY *Blink;
_LIST_ENTRY *p_ThreadListEntry;
NTSTATUS result;
char Priority;
char v24;
_LIST_ENTRY **v25;
_LIST_ENTRY *p_ProcessListEntry;
UINT64 Group;
unsigned __int64 v28;
char v29;
char v30;
UINT64 AltSeed;
__int64 CurrentIrql;
__int64 v33;
_KLOCK_QUEUE_HANDLE LockQueue;
_GROUP_AFFINITY Affinity;
HIDWORD(AltSeed) = 0;
v33 = 0i64;
p_Affinity = GroupAffinity;
Affinity = 0i64;
memset(&LockQueue, 0, sizeof(LockQueue));
if( !a3 && GroupAffinity && GroupAffinity->Mask )
{
v6 = KeSelectNodeForAffinity(GroupAffinity);
v30 = v29;
ThreadSeed = v6->ThreadSeed;
}
else
{
v6 = 0i64;
v30 = 1;
ThreadSeed = 0;
}
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Process = Thread->Tcb.ApcState.Process;
*(&Thread->Tcb.MiscFlags + 1) ^= (*(&Thread->Tcb.MiscFlags + 1) ^ (4 * Process->Pcb._bf_0)) & 8;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&Process->Pcb.ProcessLock);
BasePriority = Process->Pcb.BasePriority;
Thread->Tcb.BasePriority = BasePriority;
Thread->Tcb.Priority = BasePriority;
if( p_Affinity )
{
Group = p_Affinity->Group;
v28 = Process->Pcb.Affinity.Bitmap[Group];
if( !v28 || (v28 & p_Affinity->Mask) != p_Affinity->Mask )
KiExtendProcessAffinity(&Process->Pcb, Group);
if( !p_Affinity->Mask )
p_Affinity->Mask = Process->Pcb.Affinity.Bitmap[p_Affinity->Group];
}
else
{
if( Process == CurrentThread->Tcb.Process )
{
Affinity.Group = CurrentThread->Tcb.UserAffinity.Group;
Affinity.Mask = Process->Pcb.Affinity.Bitmap[Affinity.Group];
}
else
{
KeFirstGroupAffinityEx(&Affinity, (_BYTE)Process + 80, v10, v11);
}
p_Affinity = &Affinity;
}
Thread->Tcb.Affinity.Group = p_Affinity->Group;
Thread->Tcb.Affinity.Mask = p_Affinity->Mask;
Thread->Tcb.UserAffinity.Group = p_Affinity->Group;
Thread->Tcb.UserAffinity.Mask = p_Affinity->Mask;
KiUpdateNodeAffinitizedFlag(&Thread->Tcb);
if( a3 )
{
v14 = *(_DWORD *)a3;
}
else
{
if( !v6 )
{
v13 = p_Affinity->Group;
ThreadSeed = Process->Pcb.ThreadSeed[v13];
v6 = (_KNODE *)KeNodeBlock[Process->Pcb.IdealNode[v13]];
HIDWORD(AltSeed) = Process->Pcb.IdealProcessor[v13];
v33 = (__int64)&AltSeed + 4;
}
p_Affinity->Mask &= v6->Affinity.Mask;
LOWORD(AltSeed) = ThreadSeed;
v14 = (unsigned __int16)KeSelectIdealProcessor(v6, p_Affinity, &AltSeed);
if( v30 )
Process->Pcb.ThreadSeed[p_Affinity->Group] = AltSeed;
}
Thread->Tcb.UserIdealProcessor = v14;
p_ThreadListHead = &Process->Pcb.ThreadListHead;
Thread->Tcb.IdealProcessor = v14;
v16 = *(&KiProcessorBlock + v14);
if( p_ThreadListHead->Flink == p_ThreadListHead && Process != (_EPROCESS *)&KiInitialProcess )
{
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = &KiProcessListLock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &KiProcessListLock);
v25 = (_LIST_ENTRY **)qword_140C319F8;
p_ProcessListEntry = &Process->Pcb.ProcessListEntry;
if( *(__int64 **)qword_140C319F8 != &KiProcessListHead )
goto LABEL_45;
Process->Pcb.ProcessListEntry.Blink = (_LIST_ENTRY *)qword_140C319F8;
p_ProcessListEntry->Flink = (_LIST_ENTRY *)&KiProcessListHead;
*v25 = p_ProcessListEntry;
qword_140C319F8 = (__int64)&Process->Pcb.ProcessListEntry;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
}
*(&Thread->Tcb.MiscFlags + 1) ^= (*(&Thread->Tcb.MiscFlags + 1) ^ (Process->Pcb._bf_0 << 6)) & 0x100;
QuantumReset = (unsigned __int8)Process->Pcb.QuantumReset;
v18 = *(&Thread->Tcb.MiscFlags + 1);
Thread->Tcb.SchedulerApc.SpareByte1 = QuantumReset;
v19 = (unsigned int)(KiCyclesPerClockQuantum * QuantumReset);
if( (v18 & 0x20) != 0 )
_interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 5u);
Thread->Tcb.QuantumTarget = v19;
KiAcquireKobjectLockSafe(Process);
Blink = Process->Pcb.ThreadListHead.Blink;
p_ThreadListEntry = &Thread->Tcb.ThreadListEntry;
if( Blink->Flink != p_ThreadListHead )
LABEL_45:
__fastfail(3u);
p_ThreadListEntry->Flink = p_ThreadListHead;
Thread->Tcb.ThreadListEntry.Blink = Blink;
Blink->Flink = p_ThreadListEntry;
Process->Pcb.ThreadListHead.Blink = p_ThreadListEntry;
_InterlockedAnd((volatile signed __int32 *)Process, 0xFFFFFF7F);
if( (Process->Pcb._bf_0 & 8) != 0 )
KiFreezeSingleThread(KeGetCurrentPrcb(), &Thread->Tcb);
Thread->Tcb.SchedulingGroup = Process->Pcb.SchedulingGroup;
if( Process->Pcb.SchedulingGroup )
_interlockedbittestandset((volatile signed __int32 *)Thread, 0x12u);
KiUpdateSharedReadyQueueAffinityThread(v16, &Thread->Tcb);
if( Thread->Tcb.Process->Vm.Instance.Flags.MemoryPriority == 2
&& !Thread->Tcb.PriorityDecrement
&& (*(&Thread->Tcb.MiscFlags + 1) & 8) == 0 )
{
Priority = Thread->Tcb.Priority;
if( Priority > 0 )
{
v24 = PsPrioritySeparation + Thread->Tcb.BasePriority;
if( v24 >= 16 )
v24 = 15;
if( v24 > Priority )
{
Thread->Tcb.PriorityDecrement = (v24 - Priority) & 0xF;
KiUpdateThreadPriority(0i64, &Thread->Tcb, (unsigned int)v24, 0);
KiUpdateSharedReadyQueueAffinityThread(0i64, &Thread->Tcb);
}
}
}
if( (Thread->Tcb._bf_0 & 0x400) == 0 )
Thread->Tcb.ThreadTimerDelay = Process->Pcb.ProcessTimerDelay;
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&Process->Pcb.ProcessLock);
result = (unsigned __int8)CurrentIrql;
__writecr8((unsigned __int8)CurrentIrql);
if( (xmmword_140CFB490 & 0x8000000) != 0 )
{
EtwTraceIdealProcessor((__int64)Thread, 0x546u, -1, v14);
if( (xmmword_140CFB490 & 0x8000000) != 0 )
EtwTraceIdealProcessor((__int64)Thread, 0x547u, -1, v14);
}
_InterlockedExchangeAdd(&Process->Pcb.StackCount.Value, 8u);
return result;
}Referenced by:
KiInitializeIdleThread
PspInsertThread