KeQueryLogicalProcessorRelationship

NTSTATUS __stdcall KeQueryLogicalProcessorRelationship(
        _PROCESSOR_NUMBER *ProcessorNumber,
        _LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType,
        _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *Information,
        UINT64 *a4){
  NTSTATUS v7; 
  unsigned int v8; 
  unsigned int ProcessorIndexFromNumber; 
  __int64 v10; 
  char *v11; 
  _LOGICAL_PROCESSOR_RELATIONSHIP v12; 
  _PROCESSOR_NUMBER *v13; 
  __int64 v14; 
  ULONG v15; 
  ULONG v16; 
  __int64 v17; 
  unsigned __int64 v18; 
  int v19; 
  __int128 v21; 
  __int128 v22; 
  __int128 v23; 
  __int128 v24; 
  __int128 v25; 
  __int128 v26; 
  __int128 v27; 
  __int128 v28; 
  __int128 v29; 
  unsigned __int64 v30; 
  int v31; 
  unsigned __int16 Count; 
  USHORT v33; 
  unsigned __int64 *Bitmap; 
  __int64 v35; 
  bool v36; 
  USHORT v37; 
  __int64 v38; 
  unsigned __int16 v39; 
  GROUP_AFFINITY *GroupMask; 
  unsigned __int64 *v41; 
  unsigned __int64 v42; 
  int v43; 
  unsigned int v44; 
  unsigned int v45; 
  __int64 v46; 
  __int64 v47; 
  unsigned __int64 v48; 
  __int64 v49; 
  int v50; 
  unsigned int v51; 
  __int64 Group; 
  unsigned __int64 v53; 
  __int64 v54; 
  unsigned __int64 v55; 
  _KAFFINITY_EX *v56; 
  int v57; 
  unsigned int v58; 
  unsigned int v59; 
  int v61; 
  unsigned __int64 v62; 
  unsigned int v63; 
  unsigned int v65; 
  unsigned __int64 v66; 
  int v67; 
  _GROUP_AFFINITY GroupAffinity; 
  __int64 v69; 
  unsigned __int64 v70; 
  UINT64 *v71; 
  _KAFFINITY_EX Affinity; 
  _KAFFINITY_EX Affinity1; 
  _KAFFINITY_EX Affinity2; 
  char v75[4]; 
  char v76; 
  v71 = a4;
  memset((INT64)Affinity.Bitmap, 0i64);
  memset((INT64)Affinity1.Bitmap, 0i64);
  v7 = 0;
  v8 = 0;
  v61 = 0;
  v58 = *(_DWORD *)a4;
  if( ProcessorNumber )
  {
    ProcessorIndexFromNumber = KeGetProcessorIndexFromNumber(ProcessorNumber);
    v59 = ProcessorIndexFromNumber;
    if( ProcessorIndexFromNumber >= (unsigned int)KeNumberProcessors_0 )
      return -1073741811;
    v63 = ProcessorIndexFromNumber;
  }
  else
  {
    ProcessorIndexFromNumber = 0;
    v59 = 0;
    v63 = KeNumberProcessors_0 - 1;
  }
  v10 = 5i64;
  v65 = ProcessorIndexFromNumber;
  v11 = &v76;
  do
  {
    *(_DWORD *)v11 = 0;
    *((_DWORD *)v11 - 1) = 1310721;
    memset((INT64)(v11 + 4), 0i64);
    v11 += 168;
    --v10;
  }
  while( v10 );
  *(_DWORD *)&Affinity.Count = 1310721;
  memset((INT64)&Affinity.Reserved, 0i64);
  *(_DWORD *)&Affinity1.Count = 1310721;
  memset((INT64)&Affinity1.Reserved, 0i64);
  v12 = RelationshipType;
  GroupAffinity = 0i64;
  if( ProcessorIndexFromNumber <= v63 )
  {
    v13 = ProcessorNumber;
    while( 1 )
    {
      v14 = (__int64)*(&KiProcessorBlock + ProcessorIndexFromNumber);
      if( v12 == RelationProcessorPackage || v12 == RelationAll )
      {
        v21 = *(_OWORD *)(v14 + 33696);
        *(_OWORD *)&Affinity2.Count = *(_OWORD *)(v14 + 33680);
        v22 = *(_OWORD *)(v14 + 33712);
        *(_OWORD *)&Affinity2.Bitmap[1] = v21;
        v23 = *(_OWORD *)(v14 + 33728);
        *(_OWORD *)&Affinity2.Bitmap[3] = v22;
        v24 = *(_OWORD *)(v14 + 33744);
        *(_OWORD *)&Affinity2.Bitmap[5] = v23;
        v25 = *(_OWORD *)(v14 + 33760);
        *(_OWORD *)&Affinity2.Bitmap[7] = v24;
        v26 = *(_OWORD *)(v14 + 33776);
        *(_OWORD *)&Affinity2.Bitmap[9] = v25;
        v27 = *(_OWORD *)(v14 + 33792);
        *(_OWORD *)&Affinity2.Bitmap[11] = v26;
        v28 = *(_OWORD *)(v14 + 33808);
        *(_OWORD *)&Affinity2.Bitmap[13] = v27;
        v29 = *(_OWORD *)(v14 + 33824);
        v30 = *(_QWORD *)(v14 + 33840);
        *(_OWORD *)&Affinity2.Bitmap[15] = v28;
        *(_OWORD *)&Affinity2.Bitmap[17] = v29;
        Affinity2.Bitmap[19] = v30;
        v31 = KeAndAffinityEx(&Affinity1, &Affinity2, 0i64);
        if( v13 || !v31 )
        {
          KeOrAffinityEx(&Affinity1, &Affinity2, &Affinity1);
          Count = Affinity2.Count;
          v33 = 0;
          if( Affinity2.Count )
          {
            Bitmap = Affinity2.Bitmap;
            v35 = Affinity2.Count;
            do
            {
              v36 = *Bitmap == 0;
              v37 = v33;
              ++Bitmap;
              ++v33;
              if( v36 )
                v33 = v37;
              --v35;
            }
            while( v35 );
            ProcessorIndexFromNumber = v59;
          }
          v38 = (16 * v33 + 39) & 0xFFFFFFF8;
          v8 += v38;
          if( v8 > v58 )
          {
            v7 = -1073741820;
            v61 = -1073741820;
          }
          else
          {
            Information->Processor.GroupCount = v33;
            Information->Relationship = RelationProcessorPackage;
            Information->Size = v38;
            v39 = 0;
            Information->Group.MaximumGroupCount = 0;
            *(_OWORD *)((char *)&Information->NumaNode.NodeNumber + 2) = 0i64;
            *(_DWORD *)&Information->Group.Reserved[14] = 0;
            GroupMask = Information->Processor.GroupMask;
            if( Count )
            {
              v41 = Affinity2.Bitmap;
              do
              {
                v42 = *v41;
                if( *v41 )
                {
                  *GroupMask = 0i64;
                  GroupMask->Group = v39;
                  GroupMask->Mask = v42;
                  ++GroupMask;
                }
                ++v39;
                ++v41;
              }
              while( v39 < Count );
              v7 = v61;
            }
            Information = (_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)Information + v38);
          }
        }
      }
      if( v12 == RelationProcessorCore || v12 == RelationAll )
      {
        v48 = *(_QWORD *)(v14 + 33880);
        v49 = *(unsigned __int8 *)(v14 + 208);
        GroupAffinity.Group = *(unsigned __int8 *)(v14 + 208);
        v66 = v48;
        GroupAffinity.Mask = v48;
        v50 = KeAndGroupAffinityEx(&Affinity, &GroupAffinity, 0i64);
        if( !ProcessorNumber && v50 )
        {
          v13 = 0i64;
        }
        else
        {
          if( Affinity.Count <= (unsigned __int16)v49 )
            Affinity.Count = v49 + 1;
          Affinity.Bitmap[v49] |= v66;
          v13 = ProcessorNumber;
          v8 += 48;
          if( v8 > v58 )
          {
            v7 = -1073741820;
            v61 = -1073741820;
          }
          else
          {
            Information->Processor.Flags = *(_QWORD *)(v14 + 200) != v66;
            Information->Relationship = RelationProcessorCore;
            Information->Size = 48;
            Information->Processor.Reserved[0] = *(_BYTE *)(v14 + 33208);
            Information->Processor.GroupCount = 1;
            *(_OWORD *)((char *)&Information->NumaNode.NodeNumber + 2) = 0i64;
            *(_DWORD *)&Information->Group.Reserved[14] = 0;
            *(_OWORD *)&Information->Group.GroupInfo[0].MaximumProcessorCount = 0i64;
            Information->Processor.GroupMask[0].Group = *(unsigned __int8 *)(v14 + 208);
            Information->Processor.GroupMask[0].Mask = *(_QWORD *)(v14 + 33880);
            Information = (_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)Information + 48);
          }
        }
      }
      if( v12 == RelationAll || v12 == RelationCache )
      {
        GroupAffinity.Group = *(unsigned __int8 *)(v14 + 208);
        v51 = 0;
        v67 = 0;
        if( *(_DWORD *)(v14 + 33556) )
          break;
      }
LABEL_13:
      v59 = ++ProcessorIndexFromNumber;
      if( ProcessorIndexFromNumber > v63 )
        goto LABEL_14;
    }
    Group = GroupAffinity.Group;
    while( 1 )
    {
      v53 = *(_QWORD *)(v14 + 200);
      v54 = v51;
      v69 = v51;
      v55 = *(_QWORD *)(v14 + 8i64 * v51 + 33904);
      v62 = v55;
      if( v55 )
      {
        v70 = *(_QWORD *)(v14 + 8i64 * v51 + 33904);
        v56 = (_KAFFINITY_EX *)&v75[168 * v51];
        GroupAffinity.Mask = v55;
        v57 = KeAndGroupAffinityEx(v56, &GroupAffinity, 0i64);
        if( !ProcessorNumber && v57 )
          goto LABEL_69;
        if( v56->Count <= (unsigned __int16)Group )
          v56->Count = Group + 1;
        v56->Bitmap[Group] |= v62;
        v51 = v67;
        v54 = v69;
        v53 = v70;
      }
      v8 += 56;
      if( v8 > v58 )
      {
        v7 = -1073741820;
        goto LABEL_70;
      }
      Information->Relationship = RelationCache;
      Information->Size = 56;
      Information->Processor.Flags = *(_BYTE *)(v14 + 12 * v54 + 33496);
      Information->Processor.Reserved[0] = *(_BYTE *)(v14 + 12 * v54 + 33497);
      Information->Cache.LineSize = *(_WORD *)(v14 + 12 * v54 + 33498);
      Information->Cache.CacheSize = *(_DWORD *)(v14 + 12 * v54 + 33500);
      Information->Cache.Type = *(_DWORD *)(v14 + 12 * v54 + 33504);
      *(_OWORD *)&Information->Group.Reserved[8] = 0i64;
      *(_DWORD *)&Information->Group.GroupInfo[0].Reserved[2] = 0;
      *(_OWORD *)&Information->Group.GroupInfo[0].Reserved[6] = 0i64;
      Information->Cache.GroupMask.Group = *(unsigned __int8 *)(v14 + 208);
      Information->Cache.GroupMask.Mask = v53;
      Information = (_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)Information + 56);
LABEL_69:
      v51 = v67;
LABEL_70:
      v67 = ++v51;
      if( v51 >= *(_DWORD *)(v14 + 33556) )
      {
        ProcessorIndexFromNumber = v59;
        v12 = RelationshipType;
        v13 = ProcessorNumber;
        v61 = v7;
        goto LABEL_13;
      }
    }
  }
LABEL_14:
  if( v12 == RelationNumaNode || v12 == RelationAll )
  {
    v15 = (unsigned __int16)KeNumberNodes;
    v16 = 0;
    do
    {
      v17 = *((_QWORD *)&KeNodeBlock + v16);
      v18 = *(_QWORD *)(v17 + 136);
      if( v18 )
      {
        v19 = *(unsigned __int16 *)(v17 + 144);
        if( !ProcessorNumber
          || ((unsigned int)(v18 >> (KiProcessorIndexToNumberMappingTable[v65] & 0x3F)) & ((unsigned int)KiProcessorIndexToNumberMappingTable[v65] >> 6 == v19)) != 0 )
        {
          v8 += 48;
          if( v8 > v58 )
          {
            v7 = -1073741820;
          }
          else
          {
            Information->Size = 48;
            Information->Relationship = RelationNumaNode;
            Information->NumaNode.NodeNumber = v16;
            *(_OWORD *)Information->Group.Reserved = 0i64;
            *(_DWORD *)&Information->Group.Reserved[16] = 0;
            *(_OWORD *)&Information->Group.GroupInfo[0].MaximumProcessorCount = 0i64;
            Information->Processor.GroupMask[0].Group = v19;
            Information->Processor.GroupMask[0].Mask = v18;
            Information = (_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)Information + 48);
          }
        }
      }
      ++v16;
    }
    while( v16 < v15 );
    v12 = RelationshipType;
    v61 = v7;
  }
  if( v12 == RelationGroup || v12 == RelationAll && !ProcessorNumber )
  {
    v43 = (unsigned __int16)KiActiveGroups;
    v44 = (48 * (unsigned __int16)KiActiveGroups + 39) & 0xFFFFFFF8;
    v8 += v44;
    if( v8 > v58 )
    {
      v7 = -1073741820;
    }
    else
    {
      Information->Size = v44;
      v45 = 0;
      Information->Group.MaximumGroupCount = KiMaximumGroups;
      Information->Relationship = RelationGroup;
      Information->Cache.LineSize = v43;
      *(_OWORD *)Information->Group.Reserved = 0i64;
      *(_DWORD *)&Information->Group.Reserved[16] = 0;
      if( v43 )
      {
        do
        {
          v46 = v45;
          v47 = v45;
          Information->Cache.Reserved[48 * v45 + 12] = KeQueryMaximumProcessorCountEx(v45);
          Information->Cache.Reserved[48 * v45 + 13] = KeQueryActiveProcessorCountEx(v45);
          ++v45;
          Information->Group.GroupInfo[v47].ActiveProcessorMask = KeActiveProcessors.Bitmap[v46];
          *(_OWORD *)Information->Group.GroupInfo[v47].Reserved = 0i64;
          *(_OWORD *)&Information->Group.GroupInfo[v47].Reserved[16] = 0i64;
          *(_DWORD *)&Information->Group.GroupInfo[v47].Reserved[32] = 0;
          *(_WORD *)&Information->Group.GroupInfo[v47].Reserved[36] = 0;
        }
        while( v45 < (unsigned __int16)KiActiveGroups );
        v7 = v61;
      }
    }
  }
  if( !v7 && !v8 )
    v7 = -1073741823;
  *(_DWORD *)v71 = v8;
  return v7;
}

Referenced by:

ExpQuerySystemInformation