KiSwapToUmsThread
VOID __fastcall KiSwapToUmsThread(INT64 a2){
_ETHREAD *CurrentThread;
unsigned __int64 v3;
_ETHREAD *ThreadForTeb;
INT64 v5;
INT64 v6;
signed __int64 v7;
__int64 v8;
unsigned int v9;
INT64 v10;
INT64 v11;
unsigned __int64 v12;
void *v13;
unsigned __int64 v14;
bool v15;
unsigned __int64 NpxState;
char *Object;
INT64 v18;
INT64 v19;
_ADAPTER_OBJECT *v20;
_KPROCESSOR_MODE v21;
VOID *ThreadId;
_KTRAP_FRAME *v23;
_KEXCEPTION_FRAME *v24;
INT64 v25;
_EXCEPTION_RECORD ExceptionRecord;
memset(&ExceptionRecord, 0i64, sizeof(ExceptionRecord));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
*(_QWORD *)(a2 + 96) = CurrentThread;
v25 = *((_QWORD *)CurrentThread->Tcb.WaitBlock[3].Object + 16);
v3 = v25;
ThreadForTeb = PspFindThreadForTeb(v25);
v6 = (INT64)ThreadForTeb;
if( ThreadForTeb )
{
v7 = _InterlockedCompareExchange64((volatile signed __int64 *)&ThreadForTeb->Tcb.WaitBlock[3].SparePtr, a2, 0i64);
if( v7 == -1 )
{
v8 = *(_QWORD *)(a2 + 72);
v9 = 1;
v10 = 0i64;
HalPutDmaAdapter((PADAPTER_OBJECT)v6);
v11 = (v8 & 1) == 0;
}
else
{
if( v7 )
{
HalPutDmaAdapter((PADAPTER_OBJECT)v6);
goto LABEL_26;
}
v12 = KUSER_SHARED_DATA.XState.Size + 63 + 15i64;
if( v12 <= KUSER_SHARED_DATA.XState.Size + 63 )
v12 = 0xFFFFFFFFFFFFFF0i64;
v13 = alloca(v12 & 0xFFFFFFFFFFFFFFF0ui64);
v14 = ((unsigned __int64)&ExceptionRecord.ExceptionInformation[1] + 7) & 0xFFFFFFFFFFFFFFC0ui64;
v15 = (*(_BYTE *)(a2 + 72) & 1) == 0;
*(_QWORD *)(a2 + 64) = ((unsigned __int64)&ExceptionRecord.ExceptionInformation[1] + 7) & 0xFFFFFFFFFFFFFFC0ui64;
if( v15 )
{
KeSaveLegacyFloatingPointControlWord();
}
else if( KUSER_SHARED_DATA.XState.EnabledFeatures )
{
memset((VOID *)(v14 + 512), 0i64, 0x40u);
RtlXSave(
(_XSAVE_AREA *)(((unsigned __int64)&ExceptionRecord.ExceptionInformation[1] + 7) & 0xFFFFFFFFFFFFFFC0ui64),
KUSER_SHARED_DATA.XState.EnabledFeatures & 0xFFFFFFFFFFFFFFFDui64);
}
else
{
_fxsave((void *)v14);
}
NpxState = CurrentThread->Tcb.NpxState;
CurrentThread->Tcb.NpxState = NpxState & 0xFFFFFFFFFFFFFFFEui64;
if( (*(_BYTE *)(a2 + 72) & 1) != 0 )
KeFixUserSwitchContext(v6, **(_QWORD **)(v6 + 496), a2, 0i64);
Object = (char *)CurrentThread->Tcb.WaitBlock[3].Object;
v18 = *(_QWORD *)(v6 + 496);
v19 = *((_QWORD *)Object + 2);
if( *(_QWORD *)(v18 + 16) != v19 )
{
ObReferenceObjectSafe(v19);
v20 = *(_ADAPTER_OBJECT **)(v18 + 16);
if( v20 )
HalPutDmaAdapter(v20);
*(_QWORD *)(v18 + 16) = *((_QWORD *)Object + 2);
*(_QWORD *)(v18 + 8) = *((_QWORD *)Object + 1);
}
*(_QWORD *)(v18 + 32) = Object + 32;
*(_QWORD *)(v18 + 40) = Object + 96;
*(_DWORD *)(v18 + 24) = *((_DWORD *)Object + 6);
KiBlockAndActivateUmsThread(&CurrentThread->Tcb, (_KQUEUE *)(Object + 32), v5, v18);
CurrentThread->Tcb._bf_0 &= ~0x100u;
++*((_DWORD *)Object + 6);
v11 = *((_QWORD *)Object + 14);
if( v11 )
{
*((_QWORD *)Object + 14) = 0i64;
v9 = 2;
v10 = *((_QWORD *)Object + 15);
}
else
{
v9 = 1;
v10 = 0i64;
v11 = HIWORD(*(_DWORD *)(v6 + 116)) & 1;
}
HalPutDmaAdapter((PADAPTER_OBJECT)v6);
--CurrentThread->Tcb.SpecialApcDisable;
CurrentThread->Tcb.NpxState = NpxState;
}
KeResetLegacyFloatingPointState();
if( KeBuildPrimaryThreadContext((INT64)CurrentThread, a2, 0i64, v9, v11, v10) >= 0 )
{
KeSetCurrentUmsTeb(&CurrentThread->Tcb, (UINT64)CurrentThread->Tcb.Teb);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
return;
}
v3 = v25;
}
LABEL_26:
KeSetCurrentUmsTeb(&CurrentThread->Tcb, (UINT64)CurrentThread->Tcb.Teb);
CurrentThread->Tcb._bf_0 &= ~0x100u;
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
if( v6 )
ThreadId = PsGetThreadId((_ETHREAD *)v6);
else
ThreadId = 0i64;
v23 = *(_KTRAP_FRAME **)(a2 + 80);
v24 = *(_KEXCEPTION_FRAME **)(a2 + 88);
LOBYTE(v21) = 1;
ExceptionRecord.ExceptionAddress = 0i64;
ExceptionRecord.NumberParameters = 2;
ExceptionRecord.ExceptionInformation[0] = (unsigned __int64)ThreadId;
ExceptionRecord.ExceptionInformation[1] = v3;
ExceptionRecord.ExceptionCode = -1073740004;
ExceptionRecord.ExceptionFlags = 1;
KiDispatchException(&ExceptionRecord, v24, v23, v21, 0);
ZwTerminateProcess((VOID *)0xFFFFFFFFFFFFFFFFi64, ExceptionRecord.ExceptionCode);
ZwTerminateThread((VOID *)0xFFFFFFFFFFFFFFFEi64, ExceptionRecord.ExceptionCode);
}Referenced by:
KiUmsCallEntry
KiUmsExceptionEntry
KiUmsTrapEntry