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