KxContextToKframes

PXMM_SAVE_AREA32 __stdcall KxContextToKframes(
        PKTRAP_FRAME TrapFrame,
        PKEXCEPTION_FRAME ExceptionFrame,
        PCONTEXT ContextRecord,
        UINT32 ContextFlags,
        KPROCESSOR_MODE PreviousMode){
  unsigned __int8 v5; 
  unsigned int EFlags; 
  int v11; 
  unsigned __int64 Rip; 
  unsigned __int16 v13; 
  PXMM_SAVE_AREA32 result; 
  unsigned __int64 Dr0; 
  unsigned __int64 Dr1; 
  unsigned __int64 Dr2; 
  unsigned __int64 Dr3; 
  unsigned __int64 v19; 
  volatile signed __int32 *CurrentThread; 
  bool v21; 
  _QWORD *v22; 
  _QWORD *v23; 
  _QWORD *v24; 
  INT64 v25; 
  v5 = 0;
  if( (ContextFlags & 0x100001) == 1048577 )
  {
    EFlags = ContextRecord->EFlags;
    if( PreviousMode )
      v11 = EFlags & 0x210DD5 | 0x200;
    else
      v11 = EFlags & 0x250FD5;
    TrapFrame->EFlags = v11;
    Rip = ContextRecord->Rip;
    TrapFrame->Rip = Rip;
    TrapFrame->Rsp = ContextRecord->Rsp;
    if( PreviousMode == 1 )
    {
      TrapFrame->SegSs = 43;
      v13 = 51;
      if( ContextRecord->SegCs != 51 )
        v13 = 35;
      TrapFrame->SegCs = v13;
      Rip = TrapFrame->Rip;
      if( v13 == 35 )
        Rip = (unsigned int)Rip;
      else
        Rip = (__int64)(Rip << 16) >> 16;
    }
    else
    {
      TrapFrame->SegCs = 16;
      TrapFrame->SegSs = 24;
    }
    TrapFrame->Rip = Rip;
  }
  if( (ContextFlags & 0x100002) == 1048578 )
  {
    TrapFrame->Rax = ContextRecord->Rax;
    TrapFrame->Rcx = ContextRecord->Rcx;
    TrapFrame->Rdx = ContextRecord->Rdx;
    TrapFrame->R8 = ContextRecord->R8;
    TrapFrame->R9 = ContextRecord->R9;
    TrapFrame->R10 = ContextRecord->R10;
    TrapFrame->R11 = ContextRecord->R11;
    TrapFrame->Rbp = ContextRecord->Rbp;
    ExceptionFrame->Rbx = ContextRecord->Rbx;
    ExceptionFrame->Rsi = ContextRecord->Rsi;
    ExceptionFrame->Rdi = ContextRecord->Rdi;
    ExceptionFrame->R12 = ContextRecord->R12;
    ExceptionFrame->R13 = ContextRecord->R13;
    ExceptionFrame->R14 = ContextRecord->R14;
    ExceptionFrame->R15 = ContextRecord->R15;
  }
  if( (ContextFlags & 0x100040) == 1048640 && PreviousMode == 1 )
  {
    v22 = (_QWORD *)((char *)&ContextRecord->1 + SLODWORD(ContextRecord[1].P3Home) + 464);
    v23 = (_QWORD *)*((_QWORD *)KeGetCurrentThread() + 51);
    if( !v23 )
      goto LABEL_42;
    v24 = (_QWORD *)*v23;
    if( *v23 )
    {
      do
      {
        v23 = v24;
        v24 = (_QWORD *)*v24;
      }
      while( v24 );
    }
    v25 = v23[5];
    if( v25 )
      KiCopyXStateArea(v25, KUSER_SHARED_DATA.XState.EnabledVolatileFeatures & 0xFFFFFFFFFFFFFFFCui64, (INT64)v22);
    else
LABEL_42:
      RtlXRestoreS(
        v22,
        (KUSER_SHARED_DATA.XState.EnabledVolatileFeatures | KUSER_SHARED_DATA.XState.EnabledUserVisibleSupervisorFeatures) & 0xFFFFFFFFFFFFFFFCui64);
  }
  if( (ContextFlags & 0x100008) == 1048584 )
  {
    TrapFrame->Xmm0 = ContextRecord->Xmm0;
    TrapFrame->Xmm1 = ContextRecord->Xmm1;
    TrapFrame->Xmm2 = ContextRecord->Xmm2;
    TrapFrame->Xmm3 = ContextRecord->Xmm3;
    TrapFrame->Xmm4 = ContextRecord->Xmm4;
    TrapFrame->Xmm5 = ContextRecord->Xmm5;
    ExceptionFrame->Xmm6 = ContextRecord->Xmm6;
    ExceptionFrame->Xmm7 = ContextRecord->Xmm7;
    ExceptionFrame->Xmm8 = ContextRecord->Xmm8;
    ExceptionFrame->Xmm9 = ContextRecord->Xmm9;
    ExceptionFrame->Xmm10 = ContextRecord->Xmm10;
    ExceptionFrame->Xmm11 = ContextRecord->Xmm11;
    ExceptionFrame->Xmm12 = ContextRecord->Xmm12;
    ExceptionFrame->Xmm13 = ContextRecord->Xmm13;
    ExceptionFrame->Xmm14 = ContextRecord->Xmm14;
    ExceptionFrame->Xmm15 = ContextRecord->Xmm15;
    TrapFrame->MxCsr = KiMxCsrMask & ContextRecord->MxCsr;
    if( PreviousMode == 1 )
    {
      v5 = 1;
      ContextRecord->FltSave.MxCsr = _mm_getcsr();
      ContextRecord->FltSave.ControlWord &= 0x1F3Fu;
    }
  }
  if( (ContextFlags & 0x100010) != 1048592 )
    return(PXMM_SAVE_AREA32)v5;
  Dr0 = ContextRecord->Dr0;
  if( PreviousMode && Dr0 > 0x7FFFFFFEFFFFi64 )
    Dr0 = 0i64;
  TrapFrame->Dr0 = Dr0;
  Dr1 = ContextRecord->Dr1;
  if( PreviousMode && Dr1 > 0x7FFFFFFEFFFFi64 )
    Dr1 = 0i64;
  TrapFrame->Dr1 = Dr1;
  Dr2 = ContextRecord->Dr2;
  if( PreviousMode && Dr2 > 0x7FFFFFFEFFFFi64 )
    Dr2 = 0i64;
  TrapFrame->Dr2 = Dr2;
  Dr3 = ContextRecord->Dr3;
  if( PreviousMode && Dr3 > 0x7FFFFFFEFFFFi64 )
    Dr3 = 0i64;
  TrapFrame->Dr3 = Dr3;
  TrapFrame->Dr6 = 0i64;
  v19 = ContextRecord->Dr7 & 0xFFFF0355;
  TrapFrame->Dr7 = v19;
  if( !PreviousMode )
    return(PXMM_SAVE_AREA32)v5;
  CurrentThread = (volatile signed __int32 *)KeGetCurrentThread();
  v21 = (v19 & 0x355) == 0;
  result = (PXMM_SAVE_AREA32)v5;
  if( v21 )
    _interlockedbittestandreset(CurrentThread, 0x18u);
  else
    _interlockedbittestandset(CurrentThread, 0x18u);
  return result;
}

Referenced by:

KeContextToKframes
KiInitializeContextThread