PspSetContextThreadInternal

int __fastcall PspSetContextThreadInternal(_ETHREAD *Thread, __int64 a2, char a3, char a4, int a5){
  _ETHREAD *CurrentThread; 
  int ExtendedContextLength; 
  INT64 v11; 
  char v12; 
  __int64 v13; 
  __int64 v14; 
  __int64 v15; 
  NTSTATUS v16; 
  __int64 v17; 
  unsigned int v18; 
  unsigned __int64 v19; 
  void *v20; 
  UINT64 *v21; 
  INT64 *v22; 
  INT64 v23; 
  BYTE *v24; 
  _KAPC result; 
  char v26; 
  char v27; 
  NTSTATUS v28; 
  _KGATE Gate; 
  INT64 a1; 
  v24 = 0i64;
  memset((INT64)&result, 0i64);
  HIDWORD(v23) = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( a3 )
  {
    v17 = a2 + 48;
    if( (unsigned __int64)(a2 + 48) >= 0x7FFFFFFF0000i64 )
      v17 = 0x7FFFFFFF0000i64;
    LODWORD(v23) = *(_DWORD *)v17;
  }
  else
  {
    LODWORD(v23) = *(_DWORD *)(a2 + 48);
  }
  ExtendedContextLength = RtlpSanitizeContextFlags((UINT64 *)&v23, a3);
  if( ExtendedContextLength >= 0 )
  {
    if( !a3 )
    {
      a1 = a2;
      goto LABEL_6;
    }
    v18 = v23;
    ExtendedContextLength = RtlGetExtendedContextLength((unsigned int)v23, (UINT64 *)((char *)&v23 + 4));
    if( ExtendedContextLength >= 0 )
    {
      v19 = HIDWORD(v23) + 15i64;
      if( v19 <= HIDWORD(v23) )
        v19 = 0xFFFFFFFFFFFFFF0i64;
      v20 = alloca(v19 & 0xFFFFFFFFFFFFFFF0ui64);
      a1 = (INT64)&v23;
      memset((INT64)&v23, 0i64);
      ExtendedContextLength = RtlInitializeExtendedContext(a1, v18, &v24);
      if( ExtendedContextLength >= 0 )
      {
        a1 = (INT64)(v24 - 1232);
        LOBYTE(v21) = 1;
        ExtendedContextLength = RtlpReadExtendedContext(v22, v21, v24);
        if( ExtendedContextLength >= 0 )
        {
LABEL_6:
          if( a4 && (*((_DWORD *)Thread + 29) & 0x400) != 0 )
            return -1073741776;
          v27 &= ~4u;
          v12 = v27;
          if( a4 )
          {
            if( (a5 & 2) == 0 )
            {
              IoThreadToProcess(CurrentThread);
              v14 = v13;
              IoThreadToProcess(Thread);
              if( v15 == v14 )
              {
                v16 = KeVerifyContextRecord((_KTHREAD *)Thread, (_CONTEXT *)a1);
                if( v16 < 0 )
                  return v16;
                v12 = v27 | 4;
              }
            }
          }
          v26 = a4;
          if( Thread == CurrentThread )
          {
            result.SystemArgument1 = (void *)1;
            result.SystemArgument2 = Thread;
            v27 = v12 & 0xFC | (2 * (a5 & 1));
            --*((_WORD *)CurrentThread + 243);
            PspGetSetContextSpecialApc((unsigned __int64)&result, 0i64, 0i64, (__int64 *)&result.SystemArgument1);
            KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
LABEL_15:
            v16 = v28;
            if( v28 >= 0 && a3 == 1 && a4 == 1 )
              EtwTiLogSetContextThread(*((_BYTE *)KeGetCurrentThread() + 562), (INT64)Thread, a1, (unsigned int)v23);
            return v16;
          }
          v27 = v12 & 0xFD | (2 * (a5 & 1)) | 1;
          KeInitializeGate(&Gate, v11);
          KeInitializeApc((INT64)&result, (INT64)Thread, 0i64, (INT64)PspGetSetContextSpecialApc, 0i64, 0i64, 0, 0i64);
          if( KeInsertQueueApc(&result, (PVOID)1, Thread, 2i64) )
          {
            KeWaitForGate(&Gate, 0);
            goto LABEL_15;
          }
          return -1073741823;
        }
      }
    }
  }
  return ExtendedContextLength;
}

Referenced by:

NtSetContextThread
PsSetContextThread
PspDisassociateUmsThreadFromPrimary
PspInitializeThunkContext
PspPicoSetContextThreadEx
PspWow64SetContextThread
WbSetTrapFrame