PspDisassociateUmsThreadFromPrimary

INT64 __stdcall PspDisassociateUmsThreadFromPrimary(_ETHREAD *Thread, PADAPTER_OBJECT DmaAdapter){
  _DWORD *v2; 
  _DWORD *v3; 
  int updated; 
  unsigned __int64 CurrentUmsTeb; 
  char v8; 
  char v9; 
  __int64 v10; 
  _DWORD *v11; 
  _ETHREAD *ThreadForTeb; 
  __int64 v13; 
  int v14; 
  unsigned __int64 v15; 
  void *v16; 
  _LARGE_INTEGER *v17; 
  CONTEXT *v18; 
  INT64 v19; 
  INT64 v20; 
  void *v21; 
  __int64 v22; 
  struct _DMA_ADAPTER *v23; 
  __int64 v24; 
  UINT64 *ReturnLength; 
  UINT64 v27; 
  INT64 result; 
  INT64 v29; 
  result = 0i64;
  v3 = v2;
  LODWORD(v29) = 0;
  updated = 0;
  CurrentUmsTeb = KeGetCurrentUmsTeb((__int64)Thread);
  v8 = 0;
  v9 = 0;
  if( KeDoesTebMatchThread((INT64)Thread, CurrentUmsTeb) )
    goto LABEL_2;
  if( DmaAdapter )
  {
    if( v10 != *(_QWORD *)&DmaAdapter[15].Version )
    {
LABEL_2:
      *v11 |= 2u;
      goto LABEL_23;
    }
LABEL_10:
    v13 = *((_QWORD *)Thread + 62);
    if( (*((_DWORD *)Thread + 29) & 0x100) != 0 )
    {
      *v3 |= 1u;
      v9 = v8;
    }
    else
    {
      KeSetCurrentUmsTeb(Thread, *((_QWORD *)Thread + 30));
      v14 = KUSER_SHARED_DATA.XState.EnabledFeatures != 0 ? 0x40 : 0;
      RtlGetExtendedContextLength((unsigned int)(v14 + 1048603), (UINT64 *)&v29);
      v15 = (unsigned int)v29 + 15i64;
      if( v15 <= (unsigned int)v29 )
        v15 = 0xFFFFFFFFFFFFFF0i64;
      v16 = alloca(v15 & 0xFFFFFFFFFFFFFFF0ui64);
      memset((INT64)&result, 0i64);
      RtlInitializeExtendedContext((INT64)&result, (unsigned int)(v14 + 1048603), &result);
      LOBYTE(v17) = 1;
      v18 = (CONTEXT *)(result - 1232);
      LODWORD(ReturnLength) = 1;
      PspGetContextThreadInternal(
        Thread,
        (_TRANSACTION_NOTIFICATION *)(result - 1232),
        0i64,
        v17,
        ReturnLength,
        v27,
        result - 1232);
      v29 = **(_QWORD **)&DmaAdapter[31].Version;
      v19 = v29;
      KeFixUserSwitchContext((INT64)DmaAdapter, v29, 0i64, v18);
      updated = KeRemoveUmsThreadCidOwnership(v19, 1);
      v9 = v8;
      if( updated >= 0 )
      {
        v20 = result;
        *v3 |= 2u;
        updated = PspSetUmsThreadContext((INT64)DmaAdapter, v20, v3);
        if( updated >= 0 )
        {
          v21 = *(void **)(v13 + 16);
          if( *(void **)(*(_QWORD *)&DmaAdapter[31].Version + 16i64) != v21 )
          {
            ObReferenceObjectSafe(v21);
            v22 = *(_QWORD *)&DmaAdapter[31].Version;
            v23 = *(struct _DMA_ADAPTER **)(v22 + 16);
            if( v23 )
            {
              HalPutDmaAdapter(v23);
              v22 = *(_QWORD *)&DmaAdapter[31].Version;
            }
            *(_QWORD *)(v22 + 8) = *(_QWORD *)(v13 + 8);
            *(_QWORD *)(*(_QWORD *)&DmaAdapter[31].Version + 16i64) = *(_QWORD *)(v13 + 16);
          }
          v24 = result;
          updated = KeBuildPrimaryThreadContext((INT64)Thread, 0i64, result, 1i64, 0i64, 0i64);
          if( updated >= 0 )
          {
            PspSetContextThreadInternal(Thread, v24, 0, 1, 1);
            *v3 |= 8u;
            if( v8 )
              updated = KeUpdateUmsThreadState(v29, 0i64, 1);
          }
        }
      }
    }
    goto LABEL_23;
  }
  ThreadForTeb = PspFindThreadForTeb(v10);
  DmaAdapter = (PADAPTER_OBJECT)ThreadForTeb;
  if( !ThreadForTeb )
  {
LABEL_5:
    updated = -1073740004;
    goto LABEL_23;
  }
  v8 = 1;
  if( ExAcquireRundownProtection((PEX_RUNDOWN_REF)ThreadForTeb + 159) )
    goto LABEL_10;
  KeSetCurrentUmsTeb(Thread, *((_QWORD *)Thread + 30));
  if( _interlockedbittestandset((volatile signed __int32 *)&DmaAdapter[81], 0x10u) )
    goto LABEL_5;
LABEL_23:
  if( v8 )
  {
    if( v9 )
      ExReleaseRundownProtection((PEX_RUNDOWN_REF)&DmaAdapter[79].DmaOperations);
    HalPutDmaAdapter(DmaAdapter);
  }
  return(unsigned int)updated;
}

Referenced by:

PspRelinquishUmsThreadSpecialApc
PspUmsUnInitThread