PspWow64GetContextThread

NTSTATUS __stdcall PspWow64GetContextThread(
        _ETHREAD *Thread,
        VOID *ThreadContext,
        UINT64 ThreadContextLength,
        INT64 PreviousMode){
  char v4; 
  int v5; 
  INT64 v8; 
  INT64 v9; 
  _EPROCESS *Process; 
  _EWOW64PROCESS *WoW64Process; 
  __int64 v12; 
  NTSTATUS result; 
  unsigned int v14; 
  unsigned __int64 v15; 
  void *v16; 
  _X86_NT5_CONTEXT *v17; 
  CHAR v18; 
  _CONTEXT_EX *v19; 
  unsigned __int64 v20; 
  signed __int64 v21; 
  void *v22; 
  void *v23; 
  _CONTEXT_EX *v24; 
  _CONTEXT_EX *v25; 
  UINT64 CpuAreaContextLength; 
  UINT64 *CpuAreaContextAlignment; 
  UINT16 v28; 
  UINT8 Buffer[4]; 
  UINT64 ContextFlags; 
  NTSTATUS v31; 
  _CONTEXT_EX *ContextEx; 
  _CONTEXT_EX *v33; 
  _ETHREAD *TargetThread; 
  UINT64 v35[2]; 
  __int64 v36; 
  int CpuAreaContext[180]; 

  v4 = PreviousMode;
  v5 = ThreadContextLength;
  TargetThread = Thread;
  v33 = 0i64;
  memset(CpuAreaContext, 0i64, 0x2CCu);
  HIDWORD(ContextFlags) = 0;
  ContextEx = 0i64;
  Buffer[0] = 0;
  *(_OWORD *)v35 = 0i64;
  v36 = 0i64;
  if( v5 != 716 )
    return -1073741820;
  Process = Thread->Tcb.Process;
  WoW64Process = Process->WoW64Process;
  if( !WoW64Process || WoW64Process->Machine != 332 )
    return -1073741811;
  if( v4 )
  {
    v12 = (__int64)ThreadContext;
    if( (unsigned __int64)ThreadContext >= 0x7FFFFFFF0000i64 )
      v12 = 0x7FFFFFFF0000i64;
    LODWORD(ContextFlags) = *(_DWORD *)v12;
  }
  else
  {
    LODWORD(ContextFlags) = *(_DWORD *)ThreadContext;
  }
  LOBYTE(v8) = v4;
  result = RtlpWow64SanitizeContextFlags(&ContextFlags, v8, v9);
  if( result >= 0 )
  {
    v14 = ContextFlags;
    if( !v4 )
    {
      v17 = (_X86_NT5_CONTEXT *)ThreadContext;
      v19 = (_CONTEXT_EX *)((char *)ThreadContext + 716);
LABEL_15:
      result = PspWow64ReadOrWriteThreadCpuArea(
                 Process,
                 TargetThread,
                 1u,
                 CpuAreaContext,
                 CpuAreaContextLength,
                 (UINT64)CpuAreaContextAlignment,
                 0i64,
                 Buffer,
                 v28);
      if( result >= 0 )
      {
        if( Buffer[0] && (v14 & 0x10040) == 65600 )
        {
          return -1073741637;
        }
        else
        {
          result = RtlGetExtendedContextLength(0x4010001Fui64, (UINT64 *)((char *)&ContextFlags + 4));
          if( result >= 0 )
          {
            v20 = HIDWORD(ContextFlags) + 15i64;
            if( v20 <= HIDWORD(ContextFlags) )
              v20 = 0xFFFFFFFFFFFFFF0i64;
            v21 = v20 & 0xFFFFFFFFFFFFFFF0ui64;
            v22 = alloca(v21);
            v23 = alloca(v21);
            result = RtlInitializeExtendedContext(Buffer, 0x4010001Fui64, &v33);
            if( result >= 0 )
            {
              if( (v14 & 0x10040) == 65600 )
              {
                LODWORD(v35[1]) |= 0x100040u;
                v24 = v33;
                v33->XState = v19->XState;
                v24->XState.Offset += (_DWORD)v19 - (_DWORD)v24;
                v24->All.Length = v24->XState.Offset + v24->XState.Length - v24->All.Offset;
              }
              result = PspGetContextThreadInternal(TargetThread, (_CONTEXT *)Buffer, 0, 1, 1u);
              if( result >= 0 )
              {
                if( Buffer[0] )
                  result = RtlCopyContext(v17, (unsigned int)*v17, CpuAreaContext);
                else
                  result = RtlpWow64GetContextOnAmd64((INT64)CpuAreaContext, (INT64)Buffer, (INT64)v17);
                if( result >= 0 )
                {
                  if( v4 )
                  {
                    result = RtlpWriteExtendedContext(
                               v25,
                               (_CONTEXT_EX *)((char *)ThreadContext + 716),
                               (UINT64)v35,
                               (_CONTEXT_EX *)v14);
                    v31 = result;
                  }
                }
              }
            }
          }
        }
      }
      return result;
    }
    result = RtlGetExtendedContextLength((unsigned int)ContextFlags, (UINT64 *)((char *)&ContextFlags + 4));
    if( result >= 0 )
    {
      v15 = HIDWORD(ContextFlags) + 15i64;
      if( v15 <= HIDWORD(ContextFlags) )
        v15 = 0xFFFFFFFFFFFFFF0i64;
      v16 = alloca(v15 & 0xFFFFFFFFFFFFFFF0ui64);
      v17 = (_X86_NT5_CONTEXT *)Buffer;
      memset(Buffer, 0i64, HIDWORD(ContextFlags));
      result = RtlInitializeExtendedContext(Buffer, v14, &ContextEx);
      if( result >= 0 )
      {
        CpuAreaContextAlignment = v35;
        v19 = ContextEx;
        result = RtlpReadExtendedContext(v18, 0i64, (UINT64)ContextEx, (VOID *)v14, (_CONTEXT_EX *)ThreadContext);
        if( result >= 0 )
          goto LABEL_15;
      }
    }
  }
  return result;
}

Referenced by:

NtQueryInformationThread
WbGetWowTrapFrame
WbSetWowTrapFrame