PspInitializeThunkContext

VOID __stdcall PspInitializeThunkContext(){
  _ETHREAD *CurrentThread; 
  unsigned int v1; 
  int ExtendedContextLength; 
  UINT64 P1Home_high; 
  unsigned __int64 v4; 
  void *v5; 
  _LARGE_INTEGER *v6; 
  _CONTEXT *v7; 
  __int64 v8; 
  __int64 v9; 
  __int64 v10; 
  __int64 i; 
  UINT64 *v12; 
  UINT64 v13; 
  _CONTEXT result; 
  memset((INT64)&result.SegEs, 0i64);
  memset((char *)&result.P1Home + 4, 0, 20);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  result.P4Home = (unsigned __int64)CurrentThread;
  v1 = (*((_DWORD *)CurrentThread + 29) >> 14) & 0x40 | 0x10001B;
  ExtendedContextLength = RtlGetExtendedContextLength(v1, (UINT64 *)((char *)&result.P1Home + 4));
  if( ExtendedContextLength >= 0 )
  {
    P1Home_high = HIDWORD(result.P1Home);
    v4 = HIDWORD(result.P1Home) + 15i64;
    if( v4 <= HIDWORD(result.P1Home) )
      v4 = 0xFFFFFFFFFFFFFF0i64;
    v5 = alloca(v4 & 0xFFFFFFFFFFFFFFF0ui64);
    memset((INT64)&result, 0i64);
    ExtendedContextLength = RtlInitializeExtendedContext((INT64)&result, v1, &result.P2Home);
    if( ExtendedContextLength >= 0 )
    {
      memset((INT64)&result.R9, 0i64);
      --*((_WORD *)CurrentThread + 243);
      PspCallThreadNotifyRoutines(CurrentThread, 1u, 1u);
      LODWORD(v12) = 0;
      LOBYTE(v6) = 1;
      ExtendedContextLength = PspGetContextThreadInternal(
                                CurrentThread,
                                (_TRANSACTION_NOTIFICATION *)&result,
                                0i64,
                                v6,
                                v12,
                                v13,
                                result.P1Home);
      LODWORD(result.P1Home) = ExtendedContextLength;
      if( ExtendedContextLength >= 0 )
      {
        v7 = (_CONTEXT *)((result.Rsp - P1Home_high) & 0xFFFFFFFFFFFFFFF0ui64);
        result.FltSave.FloatRegisters[3].High = (__int64)&v7[-1].DebugControl;
        PspCreateUserContext((INT64)&result.R9, 0, PspLoaderInitRoutine, (INT64)v7, PspSystemDlls[5]);
        v8 = *(_QWORD *)(*((_QWORD *)CurrentThread + 23) + 984i64);
        if( v8 )
        {
          result.FltSave.FloatRegisters[6].High = result.FltSave.XmmRegisters[1].High;
          result.FltSave.XmmRegisters[1].High = v8;
        }
        v9 = (__int64)v7;
        if( P1Home_high - 1 > 0xFFE )
        {
          ProbeForWrite(v7, P1Home_high, 0x10ui64);
        }
        else
        {
          if( (unsigned __int64)v7 >= 0x7FFFFFFF0000i64 )
            v9 = 0x7FFFFFFF0000i64;
          *(_BYTE *)v9 = *(_BYTE *)v9;
          *(_BYTE *)(v9 + P1Home_high - 1) = *(_BYTE *)(v9 + P1Home_high - 1);
        }
        ExtendedContextLength = RtlInitializeExtendedContext((INT64)v7, v1, &result.P3Home);
        LODWORD(result.P1Home) = ExtendedContextLength;
        if( ExtendedContextLength >= 0 )
        {
          ExtendedContextLength = RtlCopyContext(v7, v1, &result);
          LODWORD(result.P1Home) = ExtendedContextLength;
          if( ExtendedContextLength >= 0 )
            KePopulateContinuationContext(result.Rip);
        }
        if( ExtendedContextLength >= 0 )
          ExtendedContextLength = PspSetContextThreadInternal(CurrentThread, (__int64)&result.R9, 0, 1, 2);
      }
    }
  }
  KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
  if( ExtendedContextLength < 0 )
  {
    *(_QWORD *)&result.ContextFlags = PspLoaderInitRoutine;
    result.P5Home = (unsigned int)ExtendedContextLength;
    *(_DWORD *)&result.SegCs = 0;
    result.P6Home = 0i64;
    v10 = *((_QWORD *)CurrentThread + 5);
    for( i = v10; (*(_BYTE *)(i + 8) & 1) != 0; i = *(_QWORD *)(i + 40) )
      ;
    if( (*(_QWORD *)(v10 + 8) & 1i64) != 0 )
    {
      do
        v10 = *(_QWORD *)(v10 + 40);
      while( (*(_BYTE *)(v10 + 8) & 1) != 0 );
    }
    KiDispatchException(
      (_EXCEPTION_RECORD *)&result.P5Home,
      (_KEXCEPTION_FRAME *)(v10 - 720),
      (_KTRAP_FRAME *)(i - 400),
      1,
      0);
  }
}

Referenced by:

PspUserThreadStartup