KiParkUmsThread

NTSTATUS __stdcall KiParkUmsThread(INT64 SparePtr){
  _ETHREAD *CurrentThread; 
  __int64 *v3; 
  __int64 v4; 
  int v5; 
  char v6; 
  unsigned int v7; 
  CHAR v8; 
  CHAR v9; 
  NTSTATUS v10; 
  unsigned __int64 v11; 
  void *v12; 
  int updated; 
  XSAVE_AREA *v14; 
  CHAR IsPrimaryPresent; 
  unsigned __int8 v16; 
  char v17; 
  unsigned __int8 CurrentIrql; 
  __int64 v19; 
  __int64 v20; 
  __int64 v21; 
  _EXCEPTION_RECORD ExitStatus; 
  INT64 result[350]; 
  memset((INT64)&ExitStatus, 0i64);
  memset((INT64)result, 0i64);
  IsPrimaryPresent = 0;
  v16 = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v3 = (__int64 *)*((_QWORD *)CurrentThread + 62);
  v4 = *v3;
  v5 = *((_DWORD *)v3 + 20);
  if( (v5 & 1) != 0 )
  {
    v6 = 1;
    *((_DWORD *)v3 + 20) = v5 & 0xFFFFFFFE;
  }
  else
  {
    v6 = 0;
  }
  v17 = v6;
  if( v6 || (*(_DWORD *)(v4 + 1264) & 0x40) != 0 )
  {
    v7 = *(_DWORD *)(v4 + 1264) & 0xFFFFFFDF;
    goto LABEL_17;
  }
  *(_DWORD *)(v4 + 1264) |= 0x20u;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(1ui64);
  v16 = 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( (*((_WORD *)KeGetCurrentPrcb() + 127) & 2) != 0 )
    v8 = 0;
  v9 = v8;
  if( *((_BYTE *)CurrentThread + 194) )
    v9 = 0;
  IsPrimaryPresent = v9;
  if( !v9 )
  {
    __writecr8(CurrentIrql);
    _enable();
    goto LABEL_8;
  }
LABEL_18:
  if( IsPrimaryPresent )
  {
    v10 = v16;
    __writecr8(v16);
    *((_DWORD *)CurrentThread + 29) &= ~0x10000u;
    return v10;
  }
  v11 = KUSER_SHARED_DATA.XState.Size + 63 + 15i64;
  if( v11 <= KUSER_SHARED_DATA.XState.Size + 63 )
    v11 = 0xFFFFFFFFFFFFFF0i64;
  v12 = alloca(v11 & 0xFFFFFFFFFFFFFFF0ui64);
  result[0] = ((unsigned __int64)&v20 + 7) & 0xFFFFFFFFFFFFFFC0ui64;
  --*((_WORD *)CurrentThread + 243);
  updated = KiCaptureUmsThreadContext((INT64)CurrentThread, SparePtr);
  if( updated < 0 )
    goto LABEL_35;
  v19 = *((_QWORD *)CurrentThread + 74);
  *((_QWORD *)CurrentThread + 74) = v19 & 0xFFFFFFFFFFFFFFFEui64;
  v3[9] = (__int64)result;
  *((_DWORD *)v3 + 20) = v3[10] & 0xFFFFFFF9 | 4;
  *((_QWORD *)CurrentThread + 63) = 0i64;
  if( v17 )
  {
    v21 = **((_QWORD **)CurrentThread + 62);
    *(_QWORD *)(v21 + 1272) = 0i64;
  }
  else
  {
    updated = KeUpdateUmsThreadState(**((_QWORD **)CurrentThread + 62), 0i64, 1);
  }
  if( updated < 0 )
    goto LABEL_35;
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  updated = KeWaitForSingleObject(v3 + 6, Executive, 1, 0, 0i64);
  if( updated != 192 )
  {
    --*((_WORD *)CurrentThread + 243);
    *((_DWORD *)v3 + 20) &= ~4u;
    SparePtr = *((_QWORD *)CurrentThread + 63);
    *((_QWORD *)CurrentThread + 74) = v19;
    if( (*(_BYTE *)(SparePtr + 72) & 1) != 0 )
    {
      v14 = *(XSAVE_AREA **)(SparePtr + 64);
      if( KUSER_SHARED_DATA.XState.EnabledVolatileFeatures )
        RtlXRestore(v14, KUSER_SHARED_DATA.XState.EnabledVolatileFeatures & 0xFFFFFFFFFFFFFFFDui64);
      else
        _fxrstor(v14);
    }
    else
    {
      KeResetLegacyFloatingPointState();
      KeRestoreLegacyFloatingPointControlWord();
    }
    KiUmsRestoreUch(SparePtr);
LABEL_35:
    KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
    goto LABEL_36;
  }
  KeGetCurrentIrql();
  __writecr8(1ui64);
  KiDeliverApc(1, 0i64, 0i64);
  __writecr8(0i64);
LABEL_36:
  ExitStatus.NumberParameters = 1;
  ExitStatus.ExceptionInformation[0] = *((_QWORD *)CurrentThread + 144);
  ExitStatus.ExceptionCode = updated;
  ExitStatus.ExceptionFlags = 1;
  ExitStatus.ExceptionAddress = 0i64;
  KiDispatchException(&ExitStatus, *(_KEXCEPTION_FRAME **)(SparePtr + 88), *(_KTRAP_FRAME **)(SparePtr + 80), 1, 0);
  ZwTerminateProcess((PVOID)0xFFFFFFFFFFFFFFFFi64, (unsigned int)ExitStatus.ExceptionCode);
  return ZwTerminateThread((PVOID)0xFFFFFFFFFFFFFFFEi64, (unsigned int)ExitStatus.ExceptionCode);
}

Referenced by:

KiUmsExit