PiQueryDeviceRelations

NTSTATUS __stdcall PiQueryDeviceRelations(
        _UNICODE_STRING *DeviceInstance,
        PNP_QUERY_RELATION Operation,
        UINT64 *BufferLength,
        WCHAR *Buffer){
  NTSTATUS v6; 
  unsigned int v7; 
  __int32 v8; 
  __int32 v9; 
  __int32 v10; 
  int v12; 
  _DEVICE_OBJECT *v13; 
  _DEVICE_OBJECT *v14; 
  _QWORD *DeviceNode; 
  _QWORD *v16; 
  unsigned int v17; 
  VOID **PoolWithTag; 
  VOID **v19; 
  unsigned int v20; 
  __int64 **i; 
  __int64 v22; 
  int DeviceRelations; 
  unsigned int v24; 
  __int64 v25; 
  unsigned __int16 *v26; 
  size_t v27; 
  WCHAR *v28; 
  void *P[7]; 

  P[0] = 0i64;
  v6 = 0;
  v7 = 0;
  if( Operation )
  {
    v8 = Operation - 1;
    if( v8 )
    {
      v9 = v8 - 1;
      if( v9 )
      {
        v10 = v9 - 1;
        if( v10 )
        {
          if( v10 != 1 )
            return -1073741811;
          v12 = 6;
        }
        else
        {
          v12 = 0;
        }
      }
      else
      {
        v12 = 2;
      }
    }
    else
    {
      v12 = 3;
    }
  }
  else
  {
    v12 = 1;
  }
  PpDevNodeLockTree(PPL_SIMPLE_READ);
  v13 = (_DEVICE_OBJECT *)PnpDeviceObjectFromDeviceInstanceWithTag((__int64)DeviceInstance, 0x43706E50u);
  v14 = v13;
  if( v13
    && (DeviceNode = v13->DeviceObjectExtension->DeviceNode, (unsigned int)(*((_DWORD *)DeviceNode + 75) - 787) > 1) )
  {
    if( v12 )
    {
      DeviceRelations = PnpQueryDeviceRelations(v13, v12, 0i64, (UINT64 *)P);
      v19 = (VOID **)P[0];
      v6 = DeviceRelations;
      if( DeviceRelations < 0 )
        v19 = 0i64;
      P[0] = v19;
    }
    else
    {
      v16 = (_QWORD *)DeviceNode[1];
      v17 = 0;
      while( v16 )
      {
        v16 = (_QWORD *)*v16;
        ++v17;
      }
      PoolWithTag = ExAllocatePoolWithTag(1ui64, 8i64 * v17 + 16, 538996816i64);
      P[0] = PoolWithTag;
      v19 = PoolWithTag;
      if( PoolWithTag )
      {
        *(_DWORD *)PoolWithTag = v17;
        v20 = 0;
        for( i = (__int64 **)DeviceNode[1]; i && v20 < v17; i = (__int64 **)*i )
        {
          ObfReferenceObjectWithTag(i[4], 0x43706E50ui64);
          v22 = v20++;
          *((_QWORD *)P[0] + v22 + 1) = i[4];
        }
        v19 = (VOID **)P[0];
      }
      else
      {
        v6 = -1073741670;
      }
    }
    if( v19 && *(_DWORD *)v19 )
    {
      v24 = 0;
      v7 = 2;
      do
      {
        v25 = *(_QWORD *)(*((_QWORD *)v19[v24 + 1] + 39) + 40i64);
        if( v25 )
        {
          v26 = (unsigned __int16 *)(v25 + 40);
          if( v25 != -40 )
          {
            v27 = *v26;
            if( (unsigned __int16)v27 >= 2u )
            {
              if( Buffer )
              {
                if( *(unsigned int *)BufferLength < (unsigned __int64)(v7 + v27) + 2 )
                {
                  v6 = -1073741789;
                  goto LABEL_46;
                }
                memmove(Buffer, *(const VOID **)(v25 + 48), v27);
                v28 = &Buffer[(unsigned __int64)*v26 >> 1];
                *v28 = 0;
                Buffer = v28 + 1;
                LOWORD(v27) = *(_WORD *)(v25 + 40);
                v19 = (VOID **)P[0];
              }
              v7 += (unsigned __int16)v27 + 2;
            }
          }
        }
        ObfDereferenceObjectWithTag(v19[v24 + 1], 0x43706E50ui64);
        v19 = (VOID **)P[0];
        ++v24;
      }
      while( v24 < *(_DWORD *)P[0] );
      if( Buffer )
      {
        if( *(_DWORD *)BufferLength >= v7 )
          *Buffer = 0;
        else
          v6 = -1073741789;
      }
    }
  }
  else
  {
    v6 = -1073741810;
  }
LABEL_46:
  PpDevNodeUnlockTree(PPL_SIMPLE_READ);
  if( v6 < 0 )
    v7 = 0;
  *(_DWORD *)BufferLength = v7;
  if( P[0] )
    ExFreePoolWithTag(P[0], 0);
  if( v14 )
    ObfDereferenceObjectWithTag(v14, 0x43706E50ui64);
  return v6;
}

Referenced by:

PiControlQueryDeviceRelations