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