PspInsertThread
__int64 __fastcall PspInsertThread(
PADAPTER_OBJECT DmaAdapter,
ULONG_PTR BugCheckParameter1,
_QWORD *a3,
_DWORD *a4,
int a5,
__int64 a6,
__int64 a7,
__int64 a8,
PACCESS_STATE AccessState,
__int64 a10,
__int64 a11){
ULONG_PTR v12;
unsigned int v14;
UINT64 *v15;
_GROUP_AFFINITY *v16;
__int64 v17;
__int64 v18;
int SecureThread;
INT64 v20;
unsigned int v22;
unsigned int v23;
_DMA_OPERATIONS **p_DmaOperations;
_DMA_OPERATIONS ***v25;
int v26;
_EPROCESS *v27;
int inserted;
volatile signed __int64 *v29;
_BYTE *v30;
INT64 v31;
int v32;
CHAR v33;
PVOID *v34;
bool v35;
UINT64 DesiredAccess;
UINT64 DesiredAccessa;
unsigned __int64 *v38;
unsigned __int64 v39;
__int64 v40;
v12 = BugCheckParameter1;
v14 = 0;
v40 = *((_QWORD *)KeGetCurrentThread() + 23);
v39 = *(_QWORD *)&DmaAdapter[15].Version;
v15 = 0i64;
v16 = 0i64;
if( a7 )
{
v38 = *(unsigned __int64 **)(a7 + 24);
v15 = (UINT64 *)((a7 + 252) & -(__int64)((*(_DWORD *)(a7 + 4) & 0x4000) != 0));
LODWORD(BugCheckParameter1) = -(*(_DWORD *)(a7 + 4) & 0x1000);
v16 = (_GROUP_AFFINITY *)((a7 + 320) & -(__int64)((*(_DWORD *)(a7 + 4) & 0x1000) != 0));
}
else
{
v38 = 0i64;
}
if( (*a4 & 0x20) == 0 )
ExAcquirePushLockExclusiveEx(v12 + 1080, 0i64);
v17 = *(_QWORD *)(v12 + 1296);
if( v17 )
{
if( (*(_DWORD *)(&DmaAdapter[7].Size + 1) & 0x400) == 0 )
{
LOBYTE(BugCheckParameter1) = 1;
ExAcquireResourceSharedLite((PERESOURCE)(v17 + 56), BugCheckParameter1);
v14 = 1;
if( v16 )
{
if( (*(_DWORD *)(v17 + 848) & 0x10) != 0 )
{
v18 = *(_QWORD *)(v17 + 8i64 * v16->Group + 624);
if( !v18 || (v18 & v16->Mask) != v16->Mask )
v14 = 5;
}
}
}
}
if( v14 < 4
&& (*(_DWORD *)(v12 + 1124) & 0x4000008) == 0x4000000
&& ((*(_DWORD *)(v12 + 1124) & 0x40000000) == 0
|| (*(_DWORD *)(&DmaAdapter[7].Size + 1) & 0x400) != 0
|| (*a4 & 2) != 0) )
{
SecureThread = 0;
}
else
{
SecureThread = -1073741823;
}
if( SecureThread >= 0 && (*(_BYTE *)(v12 + 992) & 1) != 0 )
SecureThread = PspCreateSecureThread(DmaAdapter, a8);
if( SecureThread < 0 )
{
if( (v14 & 1) != 0 )
ExReleaseResourceLite((PERESOURCE)(v17 + 56));
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v12 + 1080), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v12 + 1080));
KeAbPostRelease((PVOID)(v12 + 1080));
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)&DmaAdapter[80], 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)&DmaAdapter[80]);
KeAbPostRelease(&DmaAdapter[80]);
MmDeleteKernelStack(DmaAdapter[3].DmaOperations, 2ui64);
DmaAdapter[2].DmaOperations = 0i64;
if( a6 )
{
if( v39 )
MmDeleteTeb(v12, v39);
if( *(_BYTE *)a6 )
PspDeleteUserStack((_EPROCESS *)v12, v20, a3, (CHAR *)a6);
}
return(*(_DWORD *)(v12 + 1124) & 0x40000008) != 0 ? -1073741558 : -1073741823;
}
KeStartThread((_KTHREAD *)DmaAdapter, v16, v15);
if( (v14 & 1) != 0 )
{
ExReleaseResourceLite((PERESOURCE)(v17 + 56));
v14 &= ~1u;
}
v22 = *(_DWORD *)(v12 + 1124);
if( (v22 & 0x40000000) != 0 && (*a4 & 2) != 0 )
{
*(_DWORD *)(&DmaAdapter[81].Size + 1) |= 0x40u;
v22 = *(_DWORD *)(v12 + 1124);
}
v23 = (((v22 >> 27) & 7) << 9) | *(_DWORD *)&DmaAdapter[81].Version & 0xFFFFF1FF;
*(_DWORD *)&DmaAdapter[81].Version = v23;
*(_DWORD *)&DmaAdapter[81].Version = v23 ^ ((unsigned __int16)v23 ^ (unsigned __int16)*(_DWORD *)(v12 + 1120)) & 0x7000;
if( ++*(_DWORD *)(v12 + 1520) > *(_DWORD *)(v12 + 2136) )
*(_DWORD *)(v12 + 2136) = *(_DWORD *)(v12 + 1520);
if( *(_DWORD *)(v12 + 1520) == 1 )
{
v14 |= 2u;
}
else if( *(_DWORD *)(v12 + 1520) == 2 && (*(_DWORD *)(v12 + 1120) & 0x8000) == 0 )
{
_interlockedbittestandset((volatile signed __int32 *)(v12 + 1120), 0xFu);
}
ExAcquirePushLockExclusiveEx(v12 + 2144, 0i64);
p_DmaOperations = &DmaAdapter[78].DmaOperations;
v25 = *(_DMA_OPERATIONS ****)(v12 + 1512);
if( *v25 != (_DMA_OPERATIONS **)(v12 + 1504) )
__fastfail(3u);
*p_DmaOperations = (_DMA_OPERATIONS *)(v12 + 1504);
*(_QWORD *)&DmaAdapter[79].Version = v25;
*v25 = p_DmaOperations;
*(_QWORD *)(v12 + 1512) = p_DmaOperations;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v12 + 2144), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v12 + 2144));
KeAbPostRelease((PVOID)(v12 + 2144));
if( *(_QWORD *)(v12 + 984) )
_interlockedbittestandset((volatile signed __int32 *)DmaAdapter, 0x19u);
if( (*(_DWORD *)(v12 + 2172) & 0x2000000) != 0 )
_interlockedbittestandset((volatile signed __int32 *)DmaAdapter, 0x1Du);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(v12 + 1080), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)(v12 + 1080));
KeAbPostRelease((PVOID)(v12 + 1080));
if( (*a4 & 0x40) != 0 )
PspChangeProcessExecutionState(v12);
ObReferenceObjectExWithTag(DmaAdapter, 2ui64);
HIDWORD(DmaAdapter[85].DmaOperations) = 1;
if( (*a4 & 1) != 0 )
{
KeSuspendThread((__int64)DmaAdapter);
if( (*(_DWORD *)&DmaAdapter[81].Version & 1) != 0 )
KeForceResumeThread((_KTHREAD *)DmaAdapter);
}
v26 = 0;
if( !*((_BYTE *)AccessState + 388) || (*a4 & 0x10) != 0 )
{
v27 = (_EPROCESS *)v12;
v26 = 1;
}
else
{
v27 = (_EPROCESS *)v40;
}
LODWORD(DesiredAccess) = a5;
inserted = SeCreateAccessStateEx(
0i64,
v27,
AccessState,
(_AUX_ACCESS_DATA *)((char *)AccessState + 160),
DesiredAccess,
(_GENERIC_MAPPING *)((char *)PsThreadType + 76));
if( inserted < 0 )
{
HalPutDmaAdapter(DmaAdapter);
}
else
{
LODWORD(DesiredAccessa) = v26;
inserted = ObInsertObjectEx(DmaAdapter, AccessState, (unsigned int)a5, 0i64, DesiredAccessa, 0i64, 0i64);
if( inserted >= 0 )
{
HalPutDmaAdapter(DmaAdapter);
if( v38 )
*v38 = v39;
if( a11 )
*(struct _DMA_ADAPTER *)a11 = *(PADAPTER_OBJECT)((char *)DmaAdapter + 1144);
}
if( inserted < 0 )
{
SepDeleteAccessState(AccessState);
SeReleaseSubjectContext((_SECURITY_SUBJECT_CONTEXT *)AccessState + 1);
}
}
v29 = (volatile signed __int64 *)&DmaAdapter[80];
if( inserted < 0 )
{
if( (_InterlockedExchangeAdd64(v29, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)&DmaAdapter[80]);
KeAbPostRelease(&DmaAdapter[80]);
if( (*a4 & 1) != 0 )
KeForceResumeThread((_KTHREAD *)DmaAdapter);
v30 = (_BYTE *)a6;
if( a6 && *(_BYTE *)a6 )
PspDeleteUserStack((_EPROCESS *)v12, v31, a3, (CHAR *)a6);
}
else
{
_InterlockedOr((volatile signed __int32 *)&DmaAdapter[81], 2u);
if( (_InterlockedExchangeAdd64(v29, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)&DmaAdapter[80]);
KeAbPostRelease(&DmaAdapter[80]);
v30 = (_BYTE *)a6;
}
v32 = 0;
if( (v14 & 2) != 0 )
{
if( *(_QWORD *)(v12 + 2280) )
PoEnergyContextStart((PVOID)v12);
if( (*(_DWORD *)(v12 + 2172) & 1) == 0 || *(_QWORD *)(v12 + 2240) )
v32 = PspCallProcessNotifyRoutines((struct EX_RUNDOWN_REF *)v12, a7, 1);
}
if( (*(_DWORD *)(v12 + 2172) & 1) == 0 || *(_QWORD *)(v12 + 2240) )
PspCallThreadNotifyRoutines((_ETHREAD *)DmaAdapter, 1u, 0);
if( inserted >= 0 )
{
if( v32 < 0 )
inserted = v32;
else
inserted = PspCreateObjectHandle(DmaAdapter, (INT64)AccessState, (struct OBJECT_TYPE *)PsThreadType);
SepDeleteAccessState(AccessState);
SeReleaseSubjectContext((_SECURITY_SUBJECT_CONTEXT *)AccessState + 1);
if( inserted >= 0 )
{
if( a7 )
{
v34 = *(PVOID **)(a7 + 400);
if( v34 )
inserted = PspAssignProcessToJobList((_EPROCESS *)v12, v34, *(unsigned int *)(a7 + 412), v33);
}
if( inserted >= 0 )
{
*(_QWORD *)a10 = *((_QWORD *)AccessState + 49);
goto LABEL_121;
}
v35 = (*((_DWORD *)AccessState + 96) & 0x200) == 0 && (*(_DWORD *)(v40 + 2172) & 0x1000) == 0;
ObCloseHandle(*((PVOID *)AccessState + 49), v35);
if( v30 && (*v30 & 1) != 0 )
KeRaiseUserException((unsigned int)inserted);
}
if( !_interlockedbittestandset((volatile signed __int32 *)&DmaAdapter[81], 0) )
v14 |= 8u;
if( (*(_DWORD *)(&DmaAdapter[7].Size + 1) & 0x400) != 0 )
{
if( (*a4 & 1) != 0 )
KeForceResumeThread((_KTHREAD *)DmaAdapter);
}
else
{
if( v14 >= 8 )
LODWORD(DmaAdapter[84].DmaOperations) = inserted;
KeRequestTerminationThread((_ETHREAD *)DmaAdapter);
}
}
LABEL_121:
if( (DmaAdapter->Size & 0x4000) != 0 && inserted < 0 )
{
KeSetUmsThreadKernelLock(**(_QWORD **)&DmaAdapter[31].Version, 0i64);
KeUpdateUmsThreadState(**(_QWORD **)&DmaAdapter[31].Version, 2i64, 0);
HalPutDmaAdapter(*(PADAPTER_OBJECT *)(*(_QWORD *)&DmaAdapter[31].Version + 16i64));
KeUnInitializeUmsThread((INT64)DmaAdapter);
}
KeReadyThread((_KTHREAD *)DmaAdapter);
return(unsigned int)inserted;
}Referenced by:
NtCreateUserProcess
PspCreatePicoThread
PspCreateThread