PspEstablishJobHierarchy

INT64 __fastcall PspEstablishJobHierarchy(CHAR *Object, UINT64 a2, INT64 a3, INT64 a4){
  unsigned int v5; 
  int v8; 
  __int64 v9; 
  _QWORD *PoolWithTag; 
  unsigned __int64 v12; 
  UINT16 *v13; 
  __int64 v14; 
  void *v15; 
  CHAR **v16; 
  CHAR *v17; 
  CHAR v18; 
  int i; 
  INT64 v20; 
  void *v21; 
  _EJOB *v22; 
  __int64 v23; 
  __int64 v24; 
  __int64 v25[2]; 
  __int64 v26; 
  v5 = a4;
  *(_OWORD *)v25 = 0i64;
  v26 = 0i64;
  if( (_DWORD)a4 != 1 )
  {
    if( (_DWORD)a4 != 2 )
    {
      if( (_DWORD)a4 == 3 )
      {
        PspUnlinkJobProcess(a3, a2);
        MmLinkJobProcess((_EJOB *)Object, (_EPROCESS *)a2);
        ObfReferenceObjectWithTag(Object, 0x73507350u);
        ObfDereferenceObjectWithTag((PVOID)a3, 0x73507350ui64);
        v24 = *((_QWORD *)Object + 169);
        if( !*((_DWORD *)Object + 337) )
        {
          if( !v24 )
            goto LABEL_67;
          v24 = *(_QWORD *)(v24 + 1352);
        }
        IoSetDiskIoAttributionOnProcess(v24, a2);
        goto LABEL_67;
      }
      if( (_DWORD)a4 == 4 || (_DWORD)a4 == 5 )
        goto LABEL_13;
      if( (_DWORD)a4 != 6 )
      {
        if( (_DWORD)a4 != 7 )
        {
          v8 = -1073741811;
          goto LABEL_6;
        }
LABEL_13:
        PoolWithTag = 0i64;
        v12 = *(_QWORD *)(a3 + 1104) + 1i64;
        if( v12 > 2 )
        {
          PoolWithTag = ExAllocatePoolWithTag(PagedPool, 8 * v12 - 16, 0x624A7350ui64);
          if( !PoolWithTag )
            return 3221225626i64;
        }
        if( v5 - 4 <= 1 )
        {
          v8 = PspBindProcessSessionToJob((_EJOB *)Object, (_EPROCESS *)a2);
          if( v8 < 0 )
            goto LABEL_39;
        }
        v13 = (UINT16 *)*((_QWORD *)Object + 127);
        if( v13 )
        {
          KeRemoveSchedulingGroup(v13);
          if( (*(_DWORD *)(a3 + 1320) & 0x20) == 0 )
          {
            v8 = PspAddSchedulingGroupToJobChain((_EJOB *)a3, 0i64);
            if( v8 < 0 )
            {
              KeInsertSchedulingGroup(
                (_KSCHEDULING_GROUP *)(*((_QWORD *)Object + 126) + 128i64),
                *(_KSCHEDULING_GROUP_POLICY *)(*((_QWORD *)Object + 126) + 128i64),
                0i64);
LABEL_39:
              if( PoolWithTag )
                ExFreePoolWithTag(PoolWithTag, 0x624A7350u);
              goto LABEL_6;
            }
          }
          KeInsertSchedulingGroup(
            (_KSCHEDULING_GROUP *)(*((_QWORD *)Object + 126) + 128i64),
            *(_KSCHEDULING_GROUP_POLICY *)(*((_QWORD *)Object + 126) + 128i64),
            (_KSCHEDULING_GROUP *)(*(_QWORD *)(a3 + 1008) + 128i64));
        }
        else
        {
          v14 = *(_QWORD *)(a3 + 1016);
          if( v14 )
            *((_QWORD *)Object + 127) = v14;
        }
        v15 = Object;
        if( v5 != 4 )
          v15 = (void *)a3;
        ObfReferenceObjectWithTag(v15, 0x73507350u);
        v16 = *(CHAR ***)(a3 + 1064);
        v17 = Object + 1040;
        if( *v16 != (CHAR *)(a3 + 1056) )
          __fastfail(3u);
        *(_QWORD *)v17 = a3 + 1056;
        *((_QWORD *)Object + 131) = v16;
        *v16 = v17;
        *(_QWORD *)(a3 + 1064) = v17;
        *((_QWORD *)Object + 134) = a3;
        *((_QWORD *)Object + 135) = *(_QWORD *)(a3 + 1080);
        v18 = *(_BYTE *)(a3 + 874) + 1;
        *((_QWORD *)Object + 138) = v12;
        Object[874] = v18;
        if( v12 > 2 )
        {
          if( v12 > 3 )
          {
            v23 = *(_QWORD *)(a3 + 1104) - 2i64;
            if( *(_QWORD *)(a3 + 1104) != 2i64 )
            {
              do
              {
                PoolWithTag[v23] = *(_QWORD *)(*(_QWORD *)(a3 + 1112) + 8 * v23 - 8);
                --v23;
              }
              while( v23 );
            }
          }
          *PoolWithTag = *(_QWORD *)(a3 + 1072);
          *((_QWORD *)Object + 139) = PoolWithTag;
          PoolWithTag = 0i64;
        }
        if( v5 == 4 )
        {
          PspUnlinkJobProcess(a3, a2);
          MmLinkJobProcess((_EJOB *)Object, (_EPROCESS *)a2);
        }
        PspSetEffectiveJobLimits((__int64)Object, 0i64);
        *((_DWORD *)Object + 214) += *(_DWORD *)(a3 + 856);
        *((_DWORD *)Object + 216) += *(_DWORD *)(a3 + 864);
        *((_DWORD *)Object + 215) += *(_DWORD *)(a3 + 860);
        *((_DWORD *)Object + 217) += *(_DWORD *)(a3 + 868);
        *((_QWORD *)Object + 197) = *(_QWORD *)(a3 + 1576);
        if( (*(_DWORD *)(a3 + 1320) & 0x1841000) != 0 )
          _InterlockedOr((volatile signed __int32 *)Object + 330, *(_DWORD *)(a3 + 1320) & 0x1841000);
        for( i = 0; i < 3; ++i )
        {
          if( (unsigned int)(i - 1) > 1 )
          {
            v22 = *(_EJOB **)(a3 + 832);
            if( v22 )
              PspSetEffectiveRateControlJob((_EJOB *)Object, v22);
          }
        }
        if( *(_DWORD *)(a3 + 1348) )
        {
          v20 = a3;
        }
        else
        {
          v20 = *(_QWORD *)(a3 + 1352);
          if( v20 )
            goto LABEL_60;
        }
        if( !v20 )
        {
          if( *((_DWORD *)Object + 337) && v5 == 4 )
            IoSetDiskIoAttributionOnProcess(*((_QWORD *)Object + 169), a2);
          goto LABEL_34;
        }
LABEL_60:
        v25[1] = v20;
        LOBYTE(v26) = 1;
        PspEnumJobsAndProcessesInJobHierarchy(Object, PspSetJobIoAttributionJobPreCallback, 0i64, 0i64, (__int64)v25, 5);
LABEL_34:
        v21 = *(void **)(a3 + 1560);
        if( v21 )
        {
          ObfReferenceObjectWithTag(v21, 0x624A7350u);
          *((_QWORD *)Object + 195) = *(_QWORD *)(a3 + 1560);
          *((_QWORD *)Object + 196) = *(_QWORD *)(a3 + 1568);
        }
        if( v5 == 7 )
          _interlockedbittestandset((volatile signed __int32 *)Object + 331, 0);
        v8 = 0;
        goto LABEL_39;
      }
      _interlockedbittestandset((volatile signed __int32 *)Object + 331, 0);
    }
LABEL_67:
    v8 = 0;
    goto LABEL_6;
  }
  v8 = PspBindProcessSessionToJob((_EJOB *)Object, (_EPROCESS *)a2);
  if( v8 >= 0 )
  {
    ObfReferenceObjectWithTag(Object, 0x73507350u);
    MmLinkJobProcess((_EJOB *)Object, (_EPROCESS *)a2);
  }
  v9 = *((_QWORD *)Object + 169);
  if( !*((_DWORD *)Object + 337) )
  {
    if( !v9 )
      goto LABEL_6;
    v9 = *(_QWORD *)(v9 + 1352);
  }
  IoSetDiskIoAttributionOnProcess(v9, a2);
LABEL_6:
  if( a2 && v8 >= 0 && PsCpuFairShareEnabled )
  {
    if( (unsigned int)PsGetProcessSessionId(a2) )
      PspEstablishDfssHierarchy((INT64)Object, a2, v5);
  }
  return(unsigned int)v8;
}

Referenced by:

PspAssignProcessToJob
PspImplicitAssignProcessToJob