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