KeCopyContextFromUmsContext

NTSTATUS __fastcall KeCopyContextFromUmsContext(_CONTEXT *Destination, INT64 a2){
  unsigned int v4; 
  unsigned __int64 v5; 
  $C9F1C9CA47C010A40CE81AEC307C9F12 *v6; 
  _OWORD *v7; 
  __int64 v8; 
  _QWORD *v10; 
  UINT64 ContextFlags; 
  unsigned int v12; 

  v4 = Destination->ContextFlags;
  v12 = v4;
  LODWORD(ContextFlags) = v4 & 0x100013;
  RtlpSanitizeContextFlags(&ContextFlags, 1);
  RtlpCopyLegacyContext(1, Destination, (unsigned int)ContextFlags, (_CONTEXT *)(a2 + 16));
  v5 = (a2 + 1375) & 0xFFFFFFFFFFFFFFC0ui64;
  if( (v4 & 0x100040) == 1048640 && KUSER_SHARED_DATA.XState.EnabledFeatures )
  {
    Destination->ContextFlags |= 0x100040u;
    v10 = (unsigned __int64 *)((char *)&Destination[1].P1Home + SLODWORD(Destination[1].P3Home));
    if( (*(_DWORD *)(a2 + 1264) & 4) != 0 )
    {
      v5 = (a2 + 1375) & 0xFFFFFFFFFFFFFFC0ui64;
      KiCopyXStateArea((INT64)(v10 - 64), KUSER_SHARED_DATA.XState.EnabledFeatures & 0xFFFFFFFFFFFFFFFCui64, v5);
    }
    else
    {
      *v10 = 0i64;
      v5 = (a2 + 1375) & 0xFFFFFFFFFFFFFFC0ui64;
    }
  }
  if( (v12 & 0x100008) == 1048584 )
  {
    Destination->ContextFlags |= 0x100008u;
    v6 = &Destination->256;
    v7 = (_OWORD *)v5;
    v8 = 4i64;
    do
    {
      *(_OWORD *)&v6->FltSave.ControlWord = *v7;
      v6->Header[1] = (_M128A)v7[1];
      v6->Legacy[0] = (_M128A)v7[2];
      v6->Legacy[1] = (_M128A)v7[3];
      v6->Legacy[2] = (_M128A)v7[4];
      v6->Legacy[3] = (_M128A)v7[5];
      v6->Legacy[4] = (_M128A)v7[6];
      v6 = ($C9F1C9CA47C010A40CE81AEC307C9F12 *)((char *)v6 + 128);
      *((_OWORD *)&v6[-1].1 + 31) = v7[7];
      v7 += 8;
      --v8;
    }
    while( v8 );
    Destination->_MxCsr = *(_DWORD *)(v5 + 24);
    if( (*(_DWORD *)(a2 + 1264) & 4) == 0 )
    {
      Destination->FltSave.StatusWord = 0;
      Destination->FltSave.TagWord = 0;
    }
  }
  if( (v12 & 0x40000000) != 0 && (*(_DWORD *)(a2 + 1264) & 2) != 0 )
  {
    Destination->ContextFlags |= 0x80000000;
    if( (*(_DWORD *)(a2 + 1264) & 4) == 0 )
      Destination->ContextFlags |= 0x10000000u;
  }
  return 0;
}

Referenced by:

KeFixUserSwitchContext
PspGetSetContextInternal