PspGetContextThreadInternal

INT64 __fastcall PspGetContextThreadInternal(
        VOID *ResourceManagerHandle,
        _TRANSACTION_NOTIFICATION *TransactionNotification,
        UINT64 NotificationLength,
        _LARGE_INTEGER *Timeout,
        UINT64 *ReturnLength,
        UINT64 Asynchronous,
        UINT64 AsynchronousContext){
  char v7; 
  INT8 v8; 
  _ETHREAD *CurrentThread; 
  INT64 ExtendedContext; 
  INT64 v13; 
  BYTE *a5; 
  __int64 p_TmVirtualClock; 
  unsigned __int64 v16; 
  signed __int64 v17; 
  void *v18; 
  void *v19; 
  INT64 *v20; 
  UINT64 ContextFlags; 
  BYTE *v22; 
  _KAPC result; 
  char v24; 
  char v25; 
  unsigned int v26; 
  _KGATE Gate; 
  INT64 a1; 
  INT64 a3[2]; 
  __int64 v30; 
  v7 = (char)Timeout;
  v8 = NotificationLength;
  v22 = 0i64;
  memset((INT64)&result, 0i64);
  HIDWORD(ContextFlags) = 0;
  *(_OWORD *)a3 = 0i64;
  v30 = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( v8 )
  {
    p_TmVirtualClock = (__int64)&TransactionNotification[1].TmVirtualClock;
    if( (unsigned __int64)&TransactionNotification[1].TmVirtualClock >= 0x7FFFFFFF0000i64 )
      p_TmVirtualClock = 0x7FFFFFFF0000i64;
    LODWORD(ContextFlags) = *(_DWORD *)p_TmVirtualClock;
  }
  else
  {
    LODWORD(ContextFlags) = TransactionNotification[1].TmVirtualClock.LowPart;
  }
  LODWORD(ExtendedContext) = RtlpSanitizeContextFlags(&ContextFlags, v8);
  if( (int)ExtendedContext >= 0 )
  {
    if( v8 )
    {
      LODWORD(ExtendedContext) = RtlGetExtendedContextLength(
                                   (unsigned int)ContextFlags,
                                   (UINT64 *)((char *)&ContextFlags + 4));
      if( (int)ExtendedContext < 0 )
        return ExtendedContext;
      v16 = HIDWORD(ContextFlags) + 15i64;
      if( v16 <= HIDWORD(ContextFlags) )
        v16 = 0xFFFFFFFFFFFFFF0i64;
      v17 = v16 & 0xFFFFFFFFFFFFFFF0ui64;
      v18 = alloca(v17);
      v19 = alloca(v17);
      a1 = (INT64)&ContextFlags;
      LODWORD(ExtendedContext) = RtlInitializeExtendedContext((INT64)&ContextFlags, (unsigned int)ContextFlags, &v22);
      if( (int)ExtendedContext < 0 )
        return ExtendedContext;
      a5 = v22;
      a1 = (INT64)(v22 - 1232);
      ExtendedContext = RtlpReadExtendedContext(v20, 0i64, v22);
      if( (int)ExtendedContext < 0 )
        return ExtendedContext;
    }
    else
    {
      a1 = (INT64)TransactionNotification;
      a5 = (BYTE *)&TransactionNotification[38].TmVirtualClock;
    }
    if( v7 && (*((_DWORD *)ResourceManagerHandle + 29) & 0x400) != 0 )
      return 3221225520i64;
    v24 = v7;
    if( ResourceManagerHandle == CurrentThread )
    {
      result.SystemArgument1 = 0i64;
      result.SystemArgument2 = ResourceManagerHandle;
      v25 = v25 & 0xFC | (2 * ((unsigned __int8)ReturnLength & 1));
      --*((_WORD *)CurrentThread + 243);
      PspGetSetContextSpecialApc((unsigned __int64)&result, 0i64, 0i64, (__int64 *)&result.SystemArgument1);
      KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
    }
    else
    {
      v25 = v25 & 0xFD | (2 * ((unsigned __int8)ReturnLength & 1)) | 1;
      KeInitializeGate(&Gate, v13);
      KeInitializeApc(
        (INT64)&result,
        (INT64)ResourceManagerHandle,
        0i64,
        (INT64)PspGetSetContextSpecialApc,
        0i64,
        0i64,
        0,
        0i64);
      if( !KeInsertQueueApc(&result, 0i64, ResourceManagerHandle, 2i64) )
        return 3221225473i64;
      KeWaitForGate(&Gate, 0);
    }
    ExtendedContext = v26;
    if( (v26 & 0x80000000) == 0 && (_TRANSACTION_NOTIFICATION *)a1 != TransactionNotification )
      LODWORD(ExtendedContext) = RtlpWriteExtendedContext(
                                   a1,
                                   (INT64)&TransactionNotification[38].TmVirtualClock,
                                   (INT64)a3,
                                   *(unsigned int *)(a1 + 48),
                                   (INT64)a5);
  }
  return ExtendedContext;
}

Referenced by:

NtCreateUserProcess
NtGetContextThread
PsGetContextThread
PspDisassociateUmsThreadFromPrimary
PspInitializeThunkContext
PspPicoGetContextThreadEx
PspWow64GetContextThread
PspWow64SetContextThread
WbGetTrapFrame
WbSetTrapFrame