PiQueryDeviceRelations

__int64 __fastcall PiQueryDeviceRelations(__int64 a1, int a2, unsigned int *a3, _WORD *a4){
  int v6; 
  unsigned int v7; 
  int v8; 
  int v9; 
  int v10; 
  DEVICE_RELATION_TYPE v12; 
  _DEVICE_OBJECT *v13; 
  _DEVICE_OBJECT *v14; 
  __int64 v15; 
  _QWORD *v16; 
  unsigned int v17; 
  _DWORD *PoolWithTag; 
  _DWORD *v19; 
  unsigned int v20; 
  __int64 **i; 
  __int64 v22; 
  NTSTATUS DeviceRelations; 
  unsigned int v24; 
  __int64 v25; 
  unsigned __int16 *v26; 
  int v27; 
  _WORD *v28; 
  void *P[7]; 
  P[0] = 0i64;
  v6 = 0;
  v7 = 0;
  if( a2 )
  {
    v8 = a2 - 1;
    if( v8 )
    {
      v9 = v8 - 1;
      if( v9 )
      {
        v10 = v9 - 1;
        if( v10 )
        {
          if( v10 != 1 )
            return 3221225485i64;
          v12 = TransportRelations;
        }
        else
        {
          v12 = BusRelations;
        }
      }
      else
      {
        v12 = PowerRelations;
      }
    }
    else
    {
      v12 = RemovalRelations;
    }
  }
  else
  {
    v12 = EjectionRelations;
  }
  PpDevNodeLockTree(0);
  v13 = (_DEVICE_OBJECT *)PnpDeviceObjectFromDeviceInstanceWithTag(a1, 0x43706E50ui64);
  v14 = v13;
  if( v13 && (v15 = *(_QWORD *)(*((_QWORD *)v13 + 39) + 40i64), (unsigned int)(*(_DWORD *)(v15 + 300) - 787) > 1) )
  {
    if( v12 )
    {
      DeviceRelations = PnpQueryDeviceRelations(v13, v12, 0i64, P);
      v19 = P[0];
      v6 = DeviceRelations;
      if( DeviceRelations < 0 )
        v19 = 0i64;
      P[0] = v19;
    }
    else
    {
      v16 = *(_QWORD **)(v15 + 8);
      v17 = 0;
      while( v16 )
      {
        v16 = (_QWORD *)*v16;
        ++v17;
      }
      PoolWithTag = ExAllocatePoolWithTag(PagedPool, 8i64 * v17 + 16, 0x20207050ui64);
      P[0] = PoolWithTag;
      v19 = PoolWithTag;
      if( PoolWithTag )
      {
        *PoolWithTag = v17;
        v20 = 0;
        for( i = *(__int64 ***)(v15 + 8); i && v20 < v17; i = (__int64 **)*i )
        {
          ObfReferenceObjectWithTag(i[4], 0x43706E50u);
          v22 = v20++;
          *((_QWORD *)P[0] + v22 + 1) = i[4];
        }
        v19 = P[0];
      }
      else
      {
        v6 = -1073741670;
      }
    }
    if( v19 && *v19 )
    {
      v24 = 0;
      v7 = 2;
      do
      {
        v25 = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)&v19[2 * v24 + 2] + 312i64) + 40i64);
        if( v25 )
        {
          v26 = (unsigned __int16 *)(v25 + 40);
          if( v25 != -40 )
          {
            v27 = *v26;
            if( (unsigned __int16)v27 >= 2u )
            {
              if( a4 )
              {
                if( *a3 < (unsigned __int64)(v7 + v27) + 2 )
                {
                  v6 = -1073741789;
                  goto LABEL_46;
                }
                memmove((UINT8 *)a4, *(UINT8 **)(v25 + 48), *v26);
                v28 = &a4[(unsigned __int64)*v26 >> 1];
                *v28 = 0;
                a4 = v28 + 1;
                LOWORD(v27) = *(_WORD *)(v25 + 40);
                v19 = P[0];
              }
              v7 += (unsigned __int16)v27 + 2;
            }
          }
        }
        ObfDereferenceObjectWithTag(*(PVOID *)&v19[2 * v24 + 2], 0x43706E50ui64);
        v19 = P[0];
        ++v24;
      }
      while( v24 < *(_DWORD *)P[0] );
      if( a4 )
      {
        if( *a3 >= v7 )
          *a4 = 0;
        else
          v6 = -1073741789;
      }
    }
  }
  else
  {
    v6 = -1073741810;
  }
LABEL_46:
  PpDevNodeUnlockTree(0);
  if( v6 < 0 )
    v7 = 0;
  *a3 = v7;
  if( P[0] )
    ExFreePoolWithTag(P[0], 0);
  if( v14 )
    ObfDereferenceObjectWithTag(v14, 0x43706E50ui64);
  return(unsigned int)v6;
}

Referenced by:

PiControlQueryDeviceRelations