PnpRebalance

INT64 __fastcall PnpRebalance(UINT64 a1, VOID *a2, UINT64 a3, CHAR r9_0){
  __int64 v5; 
  INT64 v6; 
  _UNICODE_STRING *v9; 
  UINT8 *PoolWithTag; 
  UINT8 *v11; 
  int BestConfiguration; 
  int v13; 
  __int128 *v14; 
  __int64 v15; 
  _PNP_RESOURCE_REQUEST *v16; 
  unsigned int v17; 
  _PNP_RESOURCE_REQUEST *v18; 
  _OWORD *v19; 
  INT64 v20; 
  INT64 v21; 
  INT16 v22; 
  unsigned int a4; 
  _PNP_RESOURCE_REQUEST *RequestTable; 
  int v27; 
  size_t Size; 
  UINT8 *dst; 
  LIST_ENTRY ArbiterList; 
  INT64 result[2]; 
  __int128 v32; 
  __int128 v33; 
  __int128 v34; 
  __int128 v35; 
  __int64 v36; 
  v5 = (unsigned int)a3;
  v6 = *(_QWORD *)(a1 + 712);
  dst = (UINT8 *)a2;
  ArbiterList = 0i64;
  if( v6 )
    memset(v6, 0i64);
  memset((INT64)result, 0i64);
  v9 = (_UNICODE_STRING *)(a1 + 40);
  *((_QWORD *)&v33 + 1) = IopRootDeviceNode;
  *((_QWORD *)&v32 + 1) = IopRootDeviceNode;
  *((_QWORD *)&v34 + 1) = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
  LOBYTE(v34) = r9_0;
  PnpDiagnosticTraceObject(&KMPnPEvt_Rebalance_Start, (_UNICODE_STRING *)(a1 + 40));
  PoolWithTag = (UINT8 *)ExAllocatePoolWithTag(
                           PagedPool,
                           (unsigned __int64)(unsigned int)IopNumberDeviceNodes << 6,
                           0x30706E50ui64);
  v11 = PoolWithTag;
  if( !PoolWithTag )
  {
    LODWORD(v32) = 2;
    BestConfiguration = -1073741670;
    goto LABEL_17;
  }
  if( (_DWORD)v5 )
    memmove(PoolWithTag, (UINT8 *)a2, v5 << 6);
  v13 = 0;
  v14 = &v32;
  a4 = 0;
  BestConfiguration = 0;
  v15 = 0i64;
  Size = v5 << 6;
  v16 = (_PNP_RESOURCE_REQUEST *)&v11[64 * v5];
  for( RequestTable = v16; ; v16 = RequestTable )
  {
    ++HIDWORD(result[0]);
    v27 = v13;
    PnpFindRebalanceCandidates((unsigned int)v15, a1, (INT64)v16, &a4, r9_0, (INT64)result);
    v13 = a4;
    if( !(_DWORD)v5 && !r9_0 )
    {
      v17 = 0;
      if( !a4 )
      {
LABEL_13:
        BestConfiguration = -1073741823;
        if( *(_DWORD *)(a1 + 300) == 777 )
          *((_DWORD *)&v32 + v15) = 4;
        else
          *((_DWORD *)&v32 + v15) = 3;
LABEL_15:
        PnpCancelStopDeviceSubtree((ULONG_PTR)IopRootDeviceNode);
        v18 = RequestTable;
        goto LABEL_16;
      }
      while( *(_QWORD *)&v11[64 * (unsigned __int64)v17] != *(_QWORD *)(a1 + 32) )
      {
        if( ++v17 >= a4 )
          goto LABEL_13;
      }
    }
    if( v27 != a4 )
      break;
    if( !*(_DWORD *)v14 )
      *(_DWORD *)v14 = 5;
    if( BestConfiguration != -1073739512 )
      BestConfiguration = -1073741823;
LABEL_28:
    v15 = (unsigned int)(v15 + 1);
    v14 = (__int128 *)((char *)v14 + 4);
    if( (unsigned int)v15 >= 2 )
      goto LABEL_15;
  }
  BestConfiguration = PnpFindBestConfiguration((INT64)v11, (unsigned int)v5 + a4, (INT64 **)&ArbiterList);
  if( BestConfiguration < 0 )
  {
    if( !*(_DWORD *)v14 )
      *(_DWORD *)v14 = 6;
    goto LABEL_28;
  }
  PnpStopDeviceSubtree((_DEVICE_NODE *)IopRootDeviceNode, v20, v21, v22);
  IopCommitConfiguration(&ArbiterList);
  v18 = RequestTable;
  if( (_DWORD)v5 )
    PnpBuildCmResourceLists((UINT64)v11, (UINT64)RequestTable, 0);
  PnpBuildCmResourceLists((UINT64)v18, (UINT64)&v11[64 * (unsigned __int64)(unsigned int)(v5 + v13)], 1);
  if( (_DWORD)v5 )
    memmove(dst, v11, Size);
LABEL_16:
  PnpFreeResourceRequirementsForAssignTable(
    v18,
    (_PNP_RESOURCE_REQUEST *)&v11[64 * (unsigned __int64)(unsigned int)(v5 + v13)]);
  ExFreePoolWithTag(v11, 0x30706E50u);
  v9 = (_UNICODE_STRING *)(a1 + 40);
LABEL_17:
  PnpTraceRebalanceResult();
  v19 = *(_OWORD **)(a1 + 712);
  if( BestConfiguration >= 0 )
  {
    if( v19 )
    {
      ExFreePoolWithTag(v19, 0x62655250u);
      *(_QWORD *)(a1 + 712) = 0i64;
    }
  }
  else if( v19 )
  {
    *v19 = *(_OWORD *)result;
    v19[1] = v32;
    v19[2] = v33;
    v19[3] = v34;
    v19[4] = v35;
    *((_QWORD *)v19 + 10) = v36;
  }
  PnpDiagnosticTraceObjectWithStatus(&KMPnPEvt_Rebalance_Stop, v9, (unsigned int)BestConfiguration);
  return(unsigned int)BestConfiguration;
}

Referenced by:

PnpAllocateResources
PnpProcessRebalance
PnpReallocateResources