KiParkUmsThread

NTSTATUS __stdcall KiParkUmsThread(INT64 SparePtr){
  _ETHREAD *CurrentThread; 
  _DWORD *Object; 
  __int64 v4; 
  int v5; 
  char v6; 
  unsigned int v7; 
  CHAR v8; 
  CHAR v9; 
  NTSTATUS result; 
  unsigned __int64 v11; 
  void *v12; 
  int updated; 
  _KPROCESSOR_MODE v14; 
  _XSAVE_AREA *v15; 
  CHAR IsPrimaryPresent; 
  unsigned __int8 v17; 
  char v18; 
  unsigned __int8 CurrentIrql; 
  unsigned __int64 NpxState; 
  __int64 v21; 
  __int64 v22; 
  _EXCEPTION_RECORD ExceptionRecord; 
  __int64 v24[349]; 

  memset(&ExceptionRecord, 0i64, sizeof(ExceptionRecord));
  memset(v24, 0i64, sizeof(v24));
  IsPrimaryPresent = 0;
  v17 = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  Object = CurrentThread->Tcb.WaitBlock[3].Object;
  v4 = *(_QWORD *)Object;
  v5 = Object[20];
  if( (v5 & 1) != 0 )
  {
    v6 = 1;
    Object[20] = v5 & 0xFFFFFFFE;
  }
  else
  {
    v6 = 0;
  }
  v18 = v6;
  if( v6 || (*(_DWORD *)(v4 + 1264) & 0x40) != 0 )
  {
    v7 = *(_DWORD *)(v4 + 1264) & 0xFFFFFFDF;
    goto LABEL_17;
  }
  *(_DWORD *)(v4 + 1264) |= 0x20u;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(1ui64);
  v17 = CurrentIrql;
  IsPrimaryPresent = KiIsPrimaryPresent(0i64, 0i64);
  if( !IsPrimaryPresent )
  {
    __writecr8(CurrentIrql);
LABEL_8:
    v7 = *(_DWORD *)(v4 + 1264) & 0xFFFFFFDF;
LABEL_17:
    *(_DWORD *)(v4 + 1264) = v7;
    goto LABEL_18;
  }
  _disable();
  v8 = IsPrimaryPresent;
  if( (KeGetCurrentPrcb()->PairRegister & 2) != 0 )
    v8 = 0;
  v9 = v8;
  if( CurrentThread->Tcb.ApcState.UserApcPendingAll )
    v9 = 0;
  IsPrimaryPresent = v9;
  if( !v9 )
  {
    __writecr8(CurrentIrql);
    _enable();
    goto LABEL_8;
  }
LABEL_18:
  if( IsPrimaryPresent )
  {
    result = v17;
    __writecr8(v17);
    CurrentThread->Tcb._bf_0 &= ~0x10000u;
    return result;
  }
  v11 = KUSER_SHARED_DATA.XState.Size + 63 + 15i64;
  if( v11 <= KUSER_SHARED_DATA.XState.Size + 63 )
    v11 = 0xFFFFFFFFFFFFFF0i64;
  v12 = alloca(v11 & 0xFFFFFFFFFFFFFFF0ui64);
  v24[0] = ((unsigned __int64)&v21 + 7) & 0xFFFFFFFFFFFFFFC0ui64;
  --CurrentThread->Tcb.SpecialApcDisable;
  updated = KiCaptureUmsThreadContext((INT64)CurrentThread, SparePtr);
  if( updated < 0 )
    goto LABEL_35;
  NpxState = CurrentThread->Tcb.NpxState;
  CurrentThread->Tcb.NpxState = NpxState & 0xFFFFFFFFFFFFFFFEui64;
  *((_QWORD *)Object + 9) = v24;
  Object[20] = Object[20] & 0xFFFFFFF9 | 4;
  CurrentThread->Tcb.WaitBlock[3].SparePtr = 0i64;
  if( v18 )
  {
    v22 = *(_QWORD *)CurrentThread->Tcb.WaitBlock[3].Object;
    *(_QWORD *)(v22 + 1272) = 0i64;
  }
  else
  {
    updated = KeUpdateUmsThreadState(*(_QWORD *)CurrentThread->Tcb.WaitBlock[3].Object, 0i64, 1);
  }
  if( updated < 0 )
    goto LABEL_35;
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  updated = KeWaitForSingleObject((UINT64)(Object + 12), 0, 1, 0, 0i64);
  if( updated != 192 )
  {
    --CurrentThread->Tcb.SpecialApcDisable;
    Object[20] &= ~4u;
    SparePtr = (INT64)CurrentThread->Tcb.WaitBlock[3].SparePtr;
    CurrentThread->Tcb.NpxState = NpxState;
    if( (*(_BYTE *)(SparePtr + 72) & 1) != 0 )
    {
      v15 = *(_XSAVE_AREA **)(SparePtr + 64);
      if( KUSER_SHARED_DATA.XState.EnabledVolatileFeatures )
        RtlXRestore(v15, KUSER_SHARED_DATA.XState.EnabledVolatileFeatures & 0xFFFFFFFFFFFFFFFDui64);
      else
        _fxrstor(v15);
    }
    else
    {
      KeResetLegacyFloatingPointState();
      KeRestoreLegacyFloatingPointControlWord();
    }
    KiUmsRestoreUch(SparePtr);
LABEL_35:
    KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
    goto LABEL_36;
  }
  KeGetCurrentIrql();
  __writecr8(1ui64);
  KiDeliverApc(1, 0i64, 0i64);
  __writecr8(0i64);
LABEL_36:
  ExceptionRecord.NumberParameters = 1;
  ExceptionRecord.ExceptionInformation[0] = (unsigned __int64)CurrentThread->Cid.UniqueThread;
  ExceptionRecord.ExceptionCode = updated;
  ExceptionRecord.ExceptionFlags = 1;
  ExceptionRecord.ExceptionAddress = 0i64;
  LOBYTE(v14) = 1;
  KiDispatchException(&ExceptionRecord, *(PKEXCEPTION_FRAME *)(SparePtr + 88), *(PKTRAP_FRAME *)(SparePtr + 80), v14, 0);
  ZwTerminateProcess((VOID *)0xFFFFFFFFFFFFFFFFi64, ExceptionRecord.ExceptionCode);
  return ZwTerminateThread((VOID *)0xFFFFFFFFFFFFFFFEi64, ExceptionRecord.ExceptionCode);
}

Referenced by:

KiUmsExit