PspDisassociateUmsThreadFromPrimary
NTSTATUS __stdcall PspDisassociateUmsThreadFromPrimary(PETHREAD Thread, PVOID DmaAdapter, INT64 *a3){
NTSTATUS updated;
INT64 CurrentUmsTeb;
char v8;
char v9;
INT64 v10;
_DWORD *v11;
_ETHREAD *ThreadForTeb;
_QWORD *Object;
int v14;
unsigned __int64 v15;
void *v16;
_CONTEXT *v17;
INT64 v18;
_CONTEXT_EX *v19;
INT64 v20;
__int64 v21;
_ADAPTER_OBJECT *v22;
_CONTEXT *v23;
_CONTEXT *Buffer;
UINT64 ContextLength;
Buffer = 0i64;
LODWORD(ContextLength) = 0;
updated = 0;
CurrentUmsTeb = KeGetCurrentUmsTeb(Thread);
v8 = 0;
v9 = 0;
if( KeDoesTebMatchThread((INT64)Thread, CurrentUmsTeb) )
goto LABEL_2;
if( DmaAdapter )
{
if( v10 != *((_QWORD *)DmaAdapter + 30) )
{
LABEL_2:
*v11 |= 2u;
goto LABEL_23;
}
LABEL_10:
Object = Thread->Tcb.WaitBlock[3].Object;
if( (Thread->Tcb._bf_0 & 0x100) != 0 )
{
*(_DWORD *)a3 |= 1u;
v9 = v8;
}
else
{
KeSetCurrentUmsTeb(&Thread->Tcb, (UINT64)Thread->Tcb.Teb);
v14 = KUSER_SHARED_DATA.XState.EnabledFeatures != 0 ? 0x40 : 0;
RtlGetExtendedContextLength((unsigned int)(v14 + 1048603), &ContextLength);
v15 = (unsigned int)ContextLength + 15i64;
if( v15 <= (unsigned int)ContextLength )
v15 = 0xFFFFFFFFFFFFFF0i64;
v16 = alloca(v15 & 0xFFFFFFFFFFFFFFF0ui64);
memset(&Buffer, 0i64, ContextLength);
RtlInitializeExtendedContext(&Buffer, (unsigned int)(v14 + 1048603), (_CONTEXT_EX **)&Buffer);
v17 = --Buffer;
PspGetContextThreadInternal(Thread, Buffer, 0, 1, 1u);
ContextLength = **((_QWORD **)DmaAdapter + 62);
v18 = ContextLength;
KeFixUserSwitchContext((INT64)DmaAdapter, ContextLength, 0i64, v17);
updated = KeRemoveUmsThreadCidOwnership(v18, 1);
v9 = v8;
if( updated >= 0 )
{
v19 = (_CONTEXT_EX *)Buffer;
*(_DWORD *)a3 |= 2u;
updated = PspSetUmsThreadContext((__int64)DmaAdapter, (INT64)v19, a3);
if( updated >= 0 )
{
v20 = Object[2];
if( *(_QWORD *)(*((_QWORD *)DmaAdapter + 62) + 16i64) != v20 )
{
ObReferenceObjectSafe(v20);
v21 = *((_QWORD *)DmaAdapter + 62);
v22 = *(_ADAPTER_OBJECT **)(v21 + 16);
if( v22 )
{
HalPutDmaAdapter(v22);
v21 = *((_QWORD *)DmaAdapter + 62);
}
*(_QWORD *)(v21 + 8) = Object[1];
*(_QWORD *)(*((_QWORD *)DmaAdapter + 62) + 16i64) = Object[2];
}
v23 = Buffer;
updated = KeBuildPrimaryThreadContext((INT64)Thread, 0i64, (INT64)Buffer, 1i64, 0i64, 0i64);
if( updated >= 0 )
{
PspSetContextThreadInternal(Thread, v23, 0, 1, 1u);
*(_DWORD *)a3 |= 8u;
if( v8 )
updated = KeUpdateUmsThreadState(ContextLength, 0i64, 1);
}
}
}
}
goto LABEL_23;
}
ThreadForTeb = PspFindThreadForTeb(v10);
DmaAdapter = ThreadForTeb;
if( !ThreadForTeb )
{
LABEL_5:
updated = -1073740004;
goto LABEL_23;
}
v8 = 1;
if( ExAcquireRundownProtection(&ThreadForTeb->RundownProtect) )
goto LABEL_10;
KeSetCurrentUmsTeb(&Thread->Tcb, (UINT64)Thread->Tcb.Teb);
if( _interlockedbittestandset((volatile signed __int32 *)DmaAdapter + 324, 0x10u) )
goto LABEL_5;
LABEL_23:
if( v8 )
{
if( v9 )
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)DmaAdapter + 159);
HalPutDmaAdapter((PADAPTER_OBJECT)DmaAdapter);
}
return updated;
}Referenced by:
PspRelinquishUmsThreadSpecialApc
PspUmsUnInitThread