PspSetContextThreadInternal

NTSTATUS __stdcall PspSetContextThreadInternal(
        PETHREAD Thread,
        _CONTEXT *ProbeMode,
        INT8 CtxMode,
        INT8 PerformUnwind,
        UINT8 PerformUnwinda){
  _ETHREAD *CurrentThread; 
  NTSTATUS result; 
  UINT8 v11; 
  char v12; 
  _EPROCESS *v13; 
  int v14; 
  __int64 p_ContextFlags; 
  unsigned int v16; 
  unsigned __int64 v17; 
  void *v18; 
  _CONTEXT_EX *v19; 
  CHAR v20; 
  CHAR v21; 
  UINT64 ContextFlags; 
  _CONTEXT_EX *ContextEx; 
  _BYTE Apc[384]; 

  ContextEx = 0i64;
  memset(Apc, 0i64, sizeof(Apc));
  HIDWORD(ContextFlags) = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( CtxMode )
  {
    p_ContextFlags = (__int64)&ProbeMode->ContextFlags;
    if( (unsigned __int64)&ProbeMode->ContextFlags >= 0x7FFFFFFF0000i64 )
      p_ContextFlags = 0x7FFFFFFF0000i64;
    LODWORD(ContextFlags) = *(_DWORD *)p_ContextFlags;
  }
  else
  {
    LODWORD(ContextFlags) = ProbeMode->ContextFlags;
  }
  result = RtlpSanitizeContextFlags(&ContextFlags, CtxMode);
  if( result >= 0 )
  {
    if( !CtxMode )
    {
      *(_QWORD *)&Apc[120] = ProbeMode;
      goto LABEL_6;
    }
    v16 = ContextFlags;
    result = RtlGetExtendedContextLength((unsigned int)ContextFlags, (UINT64 *)((char *)&ContextFlags + 4));
    if( result >= 0 )
    {
      v17 = HIDWORD(ContextFlags) + 15i64;
      if( v17 <= HIDWORD(ContextFlags) )
        v17 = 0xFFFFFFFFFFFFFF0i64;
      v18 = alloca(v17 & 0xFFFFFFFFFFFFFFF0ui64);
      *(_QWORD *)&Apc[120] = &ContextFlags;
      memset(&ContextFlags, 0i64, HIDWORD(ContextFlags));
      result = RtlInitializeExtendedContext(*(VOID **)&Apc[120], v16, &ContextEx);
      if( result >= 0 )
      {
        *(_QWORD *)&Apc[120] = (char *)ContextEx - 1232;
        LOBYTE(v19) = 1;
        result = RtlpReadExtendedContext(v20, v19, (UINT64)ContextEx, (VOID *)v16, (_CONTEXT_EX *)ProbeMode);
        if( result >= 0 )
        {
LABEL_6:
          if( PerformUnwind && (Thread->Tcb._bf_0 & 0x400) != 0 )
            return -1073741776;
          Apc[89] &= ~4u;
          v12 = Apc[89];
          if( PerformUnwind )
          {
            if( (PerformUnwinda & 2) == 0 )
            {
              v13 = IoThreadToProcess(CurrentThread);
              if( IoThreadToProcess(Thread) == v13 )
              {
                v14 = KeVerifyContextRecord(&Thread->Tcb, *(_CONTEXT **)&Apc[120]);
                if( v14 < 0 )
                  return v14;
                v12 = Apc[89] | 4;
              }
            }
          }
          Apc[88] = PerformUnwind;
          if( Thread == CurrentThread )
          {
            *(_QWORD *)&Apc[64] = 1i64;
            *(_QWORD *)&Apc[72] = Thread;
            Apc[89] = v12 & 0xFC | (2 * (PerformUnwinda & 1));
            --CurrentThread->Tcb.SpecialApcDisable;
            PspGetSetContextSpecialApc((_KAPC *)Apc, 0i64, 0i64, (VOID **)&Apc[64]);
            KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
LABEL_15:
            v14 = *(_DWORD *)&Apc[92];
            if( *(int *)&Apc[92] >= 0 && CtxMode == 1 && PerformUnwind == 1 )
              EtwTiLogSetContextThread(
                KeGetCurrentThread()->PreviousMode,
                (INT64)Thread,
                *(INT64 *)&Apc[120],
                (unsigned int)ContextFlags);
            return v14;
          }
          Apc[89] = v12 & 0xFD | (2 * (PerformUnwinda & 1)) | 1;
          KeInitializeGate((_KGATE *)&Apc[96], v11);
          KeInitializeApc((INT64)Apc, (INT64)Thread, 0i64, (INT64)PspGetSetContextSpecialApc, 0i64, 0i64, 0, 0i64);
          if( KeInsertQueueApc((INT64)Apc, 1i64, (INT64)Thread, 2i64) )
          {
            KeWaitForGate((_KGATE *)&Apc[96], Executive, v21);
            goto LABEL_15;
          }
          return -1073741823;
        }
      }
    }
  }
  return result;
}

Referenced by:

NtSetContextThread
PsSetContextThread
PspDisassociateUmsThreadFromPrimary
PspInitializeThunkContext
PspPicoSetContextThreadEx
PspWow64SetContextThread
WbSetTrapFrame