PnpAllocateResources

__int64 __fastcall PnpAllocateResources(unsigned int a1, PNP_RESOURCE_REQUEST *a2, char a3, _BYTE *a4){
  __int64 v4; 
  _ETHREAD *CurrentThread; 
  PNP_RESOURCE_REQUEST *v9; 
  int ResourceRequirementsForAssignTable; 
  int v12; 
  int v13; 
  PNP_RESOURCE_REQUEST *v14; 
  PNP_RESOURCE_REQUEST *v15; 
  __int64 v16; 
  size_t v17; 
  PNP_RESOURCE_REQUEST *v18; 
  __int64 v19; 
  __int64 v20; 
  int v21; 
  PNP_RESOURCE_REQUEST *v22; 
  _DEVICE_NODE *v23; 
  int BestConfiguration; 
  PNP_RESOURCE_REQUEST v25; 
  size_t v26; 
  PNP_RESOURCE_REQUEST *v27; 
  PNP_RESOURCE_REQUEST *v28; 
  PNP_RESOURCE_REQUEST *v29; 
  __int128 v30; 
  __int128 v31; 
  __int128 v32; 
  __int128 v33; 
  PNP_RESOURCE_REQUEST *v34; 
  unsigned __int64 v35; 
  PNP_RESOURCE_REQUEST *i; 
  int v37; 
  _DWORD *v38; 
  unsigned __int64 v39; 
  INT64 *v40; 
  UINT64 v41; 
  _LIST_ENTRY ArbiterList; 
  size_t NumOfElements; 

  v4 = a1;
  ArbiterList = 0i64;
  if( a4 )
    *a4 = 0;
  if( !a3 )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --CurrentThread->Tcb.KernelApcDisable;
    KeWaitForSingleObject((UINT64)&PnpReplaceEvent + 6016, 4, 0, 0, 0i64);
  }
  NumOfElements = v4;
  v9 = &a2[16 * v4];
  ResourceRequirementsForAssignTable = PnpGetResourceRequirementsForAssignTable(
                                         (unsigned __int64)a2,
                                         (unsigned __int64)v9,
                                         (int *)&NumOfElements);
  if( ResourceRequirementsForAssignTable < 0 )
    goto LABEL_6;
  v12 = 0;
  v13 = 1;
  if( !*(&PnpReplaceEvent + 6680) )
  {
    v14 = a2;
    if( a2 < v9 )
    {
      while( v14[14] < 0 || *((_QWORD *)v14 + 3) )
      {
        v14 += 16;
        if( v14 >= v9 )
          goto LABEL_14;
      }
      v12 = 1;
    }
LABEL_14:
    if( v14 != v9 && a2 < v9 )
    {
      v34 = a2 + 2;
      v35 = ((unsigned __int64)((v4 << 6) - 1) >> 6) + 1;
      do
      {
        if( v34[12] < 0 || *((_QWORD *)v34 + 2) )
        {
          *v34 |= 0x20u;
          v34[12] = -1073741267;
        }
        v34 += 16;
        --v35;
      }
      while( v35 );
    }
    if( v12 )
      goto LABEL_45;
  }
  v15 = a2;
  if( a2 < v9 )
  {
    while( 1 )
    {
      v16 = *(_QWORD *)v15 ? *(_QWORD *)(*(_QWORD *)(*(_QWORD *)v15 + 312i64) + 40i64) : 0i64;
      if( (*(_DWORD *)(v16 + 396) & 0x40) != 0 && *((_QWORD *)v15 + 3) )
        break;
      v15 += 16;
      if( v15 >= v9 )
        goto LABEL_22;
    }
    v13 = 0;
  }
LABEL_22:
  if( v15 == v9 || a2 >= v9 )
  {
    v17 = NumOfElements;
  }
  else
  {
    v17 = NumOfElements;
    v18 = a2 + 2;
    do
    {
      v19 = *((_QWORD *)v18 - 1);
      if( v19 )
        v20 = *(_QWORD *)(*(_QWORD *)(v19 + 312) + 40i64);
      else
        v20 = 0i64;
      if( (*(_DWORD *)(v20 + 396) & 0x40) == 0 || !*((_QWORD *)v18 + 2) )
      {
        v25 = *v18;
        if( (*v18 & 0x20) == 0 )
        {
          v18[12] = -1073741267;
          *v18 = v25 | 0x20;
          --v17;
        }
      }
      v18 += 16;
    }
    while( v18 - 2 < v9 );
  }
  if( !v17 )
  {
    ResourceRequirementsForAssignTable = -1073741823;
    goto LABEL_45;
  }
  if( v17 != (_DWORD)v4 )
  {
    v28 = a2;
    if( a2 < v9 )
    {
      v29 = v9 - 16;
      do
      {
        if( (v28[2] & 0x20) != 0 )
        {
          v9 -= 16;
          v30 = *(_OWORD *)v28;
          v31 = *((_OWORD *)v28 + 1);
          v32 = *((_OWORD *)v28 + 2);
          v33 = *((_OWORD *)v28 + 3);
          *(_OWORD *)v28 = *(_OWORD *)v29;
          *((_OWORD *)v28 + 1) = *((_OWORD *)v29 + 1);
          *((_OWORD *)v28 + 2) = *((_OWORD *)v29 + 2);
          *((_OWORD *)v28 + 3) = *((_OWORD *)v29 + 3);
          *(_OWORD *)v29 = v30;
          *((_OWORD *)v29 + 1) = v31;
          *((_OWORD *)v29 + 2) = v32;
          *((_OWORD *)v29 + 3) = v33;
          v29 -= 16;
        }
        else
        {
          v28 += 16;
        }
      }
      while( v28 < v9 );
    }
  }
  if( v17 > 1 )
  {
    v26 = 0;
    v27 = a2 + 5;
    do
    {
      *v27 = v26++;
      v27 += 16;
    }
    while( v26 < v17 );
    qsort((UINT64)a2, v17, 0x40ui64, (INT64)PnpCompareResourceRequestPriority, v40, v41, (UINT64)ArbiterList.Flink);
  }
  if( v13 )
    ResourceRequirementsForAssignTable = PnpFindBestConfiguration((INT64)a2, v17, &ArbiterList);
  else
    ResourceRequirementsForAssignTable = -1073741823;
  if( ResourceRequirementsForAssignTable >= 0 )
  {
    ResourceRequirementsForAssignTable = IopCommitConfiguration(&ArbiterList);
    for( i = a2; i < v9; i += 16 )
    {
      if( ResourceRequirementsForAssignTable < 0 )
        i[14] = -1073741800;
      else
        PnpBuildCmResourceLists((unsigned __int64)i, (unsigned __int64)(i + 16), 0);
    }
    goto LABEL_44;
  }
  v21 = 0;
  v22 = a2;
  if( a2 >= v9 )
    goto LABEL_44;
  while( 1 )
  {
    if( *(_QWORD *)v22 )
      v23 = *(_DEVICE_NODE **)(*(_QWORD *)(*(_QWORD *)v22 + 312i64) + 40i64);
    else
      v23 = 0i64;
    BestConfiguration = PnpFindBestConfiguration((INT64)v22, 1ui64, &ArbiterList);
    ResourceRequirementsForAssignTable = BestConfiguration;
    if( BestConfiguration >= 0 )
    {
      v21 = 1;
      ResourceRequirementsForAssignTable = IopCommitConfiguration(&ArbiterList);
      if( ResourceRequirementsForAssignTable < 0 )
        v22[14] = -1073741800;
      else
        PnpBuildCmResourceLists((unsigned __int64)v22, (unsigned __int64)(v22 + 16), 0);
      goto LABEL_42;
    }
    if( BestConfiguration == -1073741670 )
      goto LABEL_43;
    if( !v21 && (a2[2] & 0x80u) == 0 )
      break;
    v22[2] |= 0x20u;
    v22[14] = -1073741267;
LABEL_42:
    v22 += 16;
    if( v22 >= v9 )
      goto LABEL_43;
  }
  PipSetDevNodeFlags(v23, 0x40000ui64);
  ResourceRequirementsForAssignTable = PnpRebalance((__int64)v23, v22, 1u, 0);
  PipClearDevNodeFlags(v23, 0x40000ui64);
  if( ResourceRequirementsForAssignTable < 0 )
  {
    v37 = -1073741800;
    if( ResourceRequirementsForAssignTable == -1073739512 )
      v37 = -1073739512;
    v22[14] = v37;
    goto LABEL_42;
  }
  if( a4 )
    *a4 = 1;
  v22 += 16;
LABEL_43:
  if( v22 < v9 )
  {
    if( ResourceRequirementsForAssignTable == -1073741670 )
    {
      do
      {
        v22[14] = -1073741670;
        v22 += 16;
      }
      while( v22 < v9 );
    }
    else
    {
      v38 = v22 + 2;
      v39 = ((unsigned __int64)((char *)v9 - (char *)v22 - 1) >> 6) + 1;
      do
      {
        *v38 |= 0x20u;
        v38[12] = -1073741267;
        v38 += 16;
        --v39;
      }
      while( v39 );
    }
  }
LABEL_44:
  IopReleaseFilteredBootResources(a2, v9);
LABEL_45:
  PnpFreeResourceRequirementsForAssignTable((unsigned __int64)a2, (unsigned __int64)v9);
LABEL_6:
  if( !a3 )
  {
    KeReleaseSemaphore((_KSEMAPHORE *)&PnpReplaceEvent + 188, 0i64, 1i64, 0);
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
  }
  return(unsigned int)ResourceRequirementsForAssignTable;
}

Referenced by:

IopLegacyResourceAllocation
PnpAssignResourcesToDevices