PnpAllocateResources

INT64 __fastcall PnpAllocateResources(
        UINT64 RequestCount,
        _PNP_RESOURCE_REQUEST *Request,
        UINT64 ResourceManagerLocked,
        UINT *RebalancePerformed){
  __int64 v4; 
  char v6; 
  _ETHREAD *CurrentThread; 
  _PNP_RESOURCE_REQUEST *v9; 
  int v10; 
  int BestConfiguration; 
  int v13; 
  int v14; 
  _PNP_RESOURCE_REQUEST *v15; 
  _PNP_RESOURCE_REQUEST *v16; 
  __int64 v17; 
  unsigned int v18; 
  unsigned int *v19; 
  __int64 v20; 
  __int64 v21; 
  int v22; 
  _PNP_RESOURCE_REQUEST *v23; 
  _DEVICE_NODE *v24; 
  int v25; 
  unsigned int v26; 
  unsigned int v27; 
  unsigned int *p_Position; 
  _PNP_RESOURCE_REQUEST *v29; 
  _PNP_RESOURCE_REQUEST *v30; 
  __int128 v31; 
  __int128 v32; 
  __int128 v33; 
  __int128 v34; 
  unsigned int *p_Flags; 
  unsigned __int64 v36; 
  _PNP_RESOURCE_REQUEST *i; 
  int v38; 
  unsigned int *v39; 
  unsigned __int64 v40; 
  LIST_ENTRY ArbiterList; 
  size_t NumOfElements; 
  v4 = (unsigned int)RequestCount;
  v6 = ResourceManagerLocked;
  ArbiterList = 0i64;
  if( RebalancePerformed )
    *(_BYTE *)RebalancePerformed = 0;
  if( !(_BYTE)ResourceManagerLocked )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)CurrentThread + 242);
    KeWaitForSingleObject(&PpRegistrySemaphore, DelayExecution, 0, 0, 0i64);
  }
  LODWORD(NumOfElements) = v4;
  v9 = &Request[v4];
  PnpGetResourceRequirementsForAssignTable(Request, v9, &NumOfElements, (INT64)RebalancePerformed);
  BestConfiguration = v10;
  if( v10 < 0 )
    goto LABEL_6;
  v13 = 0;
  v14 = 1;
  if( !IopBootConfigsReserved )
  {
    v15 = Request;
    if( Request < v9 )
    {
      while( v15->Status < 0 || v15->ResourceRequirements )
      {
        if( ++v15 >= v9 )
          goto LABEL_14;
      }
      v13 = 1;
    }
LABEL_14:
    if( v15 != v9 && Request < v9 )
    {
      p_Flags = &Request->Flags;
      v36 = ((unsigned __int64)((v4 << 6) - 1) >> 6) + 1;
      do
      {
        if( (p_Flags[12] & 0x80000000) != 0 || *((_QWORD *)p_Flags + 2) )
        {
          *p_Flags |= 0x20u;
          p_Flags[12] = -1073741267;
        }
        p_Flags += 16;
        --v36;
      }
      while( v36 );
    }
    if( v13 )
      goto LABEL_45;
  }
  v16 = Request;
  if( Request < v9 )
  {
    while( 1 )
    {
      v17 = v16->PhysicalDevice ? *(_QWORD *)(*((_QWORD *)v16->PhysicalDevice + 39) + 40i64) : 0i64;
      if( (*(_DWORD *)(v17 + 396) & 0x40) != 0 && v16->ResourceRequirements )
        break;
      if( ++v16 >= v9 )
        goto LABEL_22;
    }
    v14 = 0;
  }
LABEL_22:
  if( v16 == v9 || Request >= v9 )
  {
    v18 = NumOfElements;
  }
  else
  {
    v18 = NumOfElements;
    v19 = &Request->Flags;
    do
    {
      v20 = *((_QWORD *)v19 - 1);
      if( v20 )
        v21 = *(_QWORD *)(*(_QWORD *)(v20 + 312) + 40i64);
      else
        v21 = 0i64;
      if( (*(_DWORD *)(v21 + 396) & 0x40) == 0 || !*((_QWORD *)v19 + 2) )
      {
        v26 = *v19;
        if( (*v19 & 0x20) == 0 )
        {
          v19[12] = -1073741267;
          *v19 = v26 | 0x20;
          --v18;
        }
      }
      v19 += 16;
    }
    while( v19 - 2 < (unsigned int *)v9 );
  }
  if( !v18 )
  {
    BestConfiguration = -1073741823;
    goto LABEL_45;
  }
  if( v18 != (_DWORD)v4 )
  {
    v29 = Request;
    if( Request < v9 )
    {
      v30 = v9 - 1;
      do
      {
        if( (v29->Flags & 0x20) != 0 )
        {
          --v9;
          v31 = *(_OWORD *)&v29->PhysicalDevice;
          v32 = *(_OWORD *)&v29->Priority;
          v33 = *(_OWORD *)&v29->ReqList;
          v34 = *(_OWORD *)&v29->TranslatedResourceAssignment;
          *(_OWORD *)&v29->PhysicalDevice = *(_OWORD *)&v30->PhysicalDevice;
          *(_OWORD *)&v29->Priority = *(_OWORD *)&v30->Priority;
          *(_OWORD *)&v29->ReqList = *(_OWORD *)&v30->ReqList;
          *(_OWORD *)&v29->TranslatedResourceAssignment = *(_OWORD *)&v30->TranslatedResourceAssignment;
          *(_OWORD *)&v30->PhysicalDevice = v31;
          *(_OWORD *)&v30->Priority = v32;
          *(_OWORD *)&v30->ReqList = v33;
          *(_OWORD *)&v30->TranslatedResourceAssignment = v34;
          --v30;
        }
        else
        {
          ++v29;
        }
      }
      while( v29 < v9 );
    }
  }
  if( v18 > 1 )
  {
    v27 = 0;
    p_Position = &Request->Position;
    do
    {
      *p_Position = v27++;
      p_Position += 16;
    }
    while( v27 < v18 );
    qsort((WCHAR *)Request, v18, (const WCHAR *)0x40, PnpCompareResourceRequestPriority);
  }
  if( v14 )
    BestConfiguration = PnpFindBestConfiguration((INT64)Request, v18, (INT64 **)&ArbiterList);
  else
    BestConfiguration = -1073741823;
  if( BestConfiguration >= 0 )
  {
    BestConfiguration = IopCommitConfiguration(&ArbiterList);
    for( i = Request; i < v9; ++i )
    {
      if( BestConfiguration < 0 )
        i->Status = -1073741800;
      else
        PnpBuildCmResourceLists((UINT64)i, (UINT64)&i[1], 0);
    }
    goto LABEL_44;
  }
  v22 = 0;
  v23 = Request;
  if( Request >= v9 )
    goto LABEL_44;
  while( 1 )
  {
    if( v23->PhysicalDevice )
      v24 = *(_DEVICE_NODE **)(*((_QWORD *)v23->PhysicalDevice + 39) + 40i64);
    else
      v24 = 0i64;
    v25 = PnpFindBestConfiguration((INT64)v23, 1ui64, (INT64 **)&ArbiterList);
    BestConfiguration = v25;
    if( v25 >= 0 )
    {
      v22 = 1;
      BestConfiguration = IopCommitConfiguration(&ArbiterList);
      if( BestConfiguration < 0 )
        v23->Status = -1073741800;
      else
        PnpBuildCmResourceLists((UINT64)v23, (UINT64)&v23[1], 0);
      goto LABEL_42;
    }
    if( v25 == -1073741670 )
      goto LABEL_43;
    if( !v22 && (Request->Flags & 0x80u) == 0 )
      break;
    v23->Flags |= 0x20u;
    v23->Status = -1073741267;
LABEL_42:
    if( ++v23 >= v9 )
      goto LABEL_43;
  }
  PipSetDevNodeFlags((__int64)v24, 0x40000);
  BestConfiguration = PnpRebalance((UINT64)v24, v23, 1ui64, 0);
  PipClearDevNodeFlags(v24, 0x40000ui64);
  if( BestConfiguration < 0 )
  {
    v38 = -1073741800;
    if( BestConfiguration == -1073739512 )
      v38 = -1073739512;
    v23->Status = v38;
    goto LABEL_42;
  }
  if( RebalancePerformed )
    *(_BYTE *)RebalancePerformed = 1;
  ++v23;
LABEL_43:
  if( v23 < v9 )
  {
    if( BestConfiguration == -1073741670 )
    {
      do
      {
        v23->Status = -1073741670;
        ++v23;
      }
      while( v23 < v9 );
    }
    else
    {
      v39 = &v23->Flags;
      v40 = ((unsigned __int64)((char *)v9 - (char *)v23 - 1) >> 6) + 1;
      do
      {
        *v39 |= 0x20u;
        v39[12] = -1073741267;
        v39 += 16;
        --v40;
      }
      while( v40 );
    }
  }
LABEL_44:
  IopReleaseFilteredBootResources((UINT64)Request, (UINT64)v9);
LABEL_45:
  PnpFreeResourceRequirementsForAssignTable(Request, v9);
LABEL_6:
  if( !v6 )
  {
    KeReleaseSemaphore(&PpRegistrySemaphore, 0i64, 1i64, 0);
    KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  }
  return(unsigned int)BestConfiguration;
}

Referenced by:

IopLegacyResourceAllocation
PnpAssignResourcesToDevices