MiProcessCrcList
__int64 *__fastcall MiProcessCrcList(__int64 a1, __int64 *a2, size_t a3, int a4){
unsigned int v4;
__int64 *result;
__int64 v7;
INT64 v8;
size_t v9;
unsigned __int64 v10;
PADAPTER_OBJECT v11;
_MMPFN *PfnDb;
INT64 *CombineProto;
char *v14;
unsigned __int64 v15;
unsigned int v16;
_MMPTE **v17;
__int64 v18;
__int64 v19;
unsigned __int64 v20;
_MMPTE **v21;
_MMSUPPORT_FULL *v22;
__int64 v23;
_QWORD *v24;
_QWORD *v25;
_QWORD *v26;
bool v27;
_QWORD *v28;
WCHAR *v29;
WCHAR *v30;
_QWORD *v31;
__int64 v32;
_QWORD *j;
__int64 i;
_QWORD **v35;
_QWORD *v36;
_QWORD *v37;
UINT64 *v38;
size_t v39;
_QWORD **v40;
UINT64 *v41;
unsigned __int64 v42;
__int64 v43;
INT64 v44;
_QWORD *v45;
size_t v46;
INT64 v47;
INT64 *v48;
size_t k;
INT64 v50;
__int64 v51;
struct _DMA_ADAPTER *v52;
INT64 v53;
INT64 *v54;
int v55;
__int64 v56;
INT64 a5;
size_t NumOfElements;
PVOID P;
PADAPTER_OBJECT DmaAdapter;
__int64 *v61;
int v62;
int v63;
INT64 a3a[2];
__int64 a4a;
INT64 v66;
VOID **ReferencedObject;
INT64 a1a;
__int64 v69;
unsigned __int64 v70;
INT64 v71;
INT64 v72[2];
__int64 v73;
v4 = a4;
v61 = a2;
v66 = a1;
result = a2;
v63 = a4;
v69 = 0i64;
v62 = 0;
a4a = 0i64;
v73 = 0i64;
*(_OWORD *)v72 = 0i64;
if( a3 )
{
v7 = *(_QWORD *)(a1 + 8);
v8 = *(_QWORD *)a1;
LODWORD(ReferencedObject) = *(_DWORD *)(a1 + 60);
P = 0i64;
a1a = v8;
v71 = v8;
qsort((WCHAR *)a2, a3, (const WCHAR *)0x28, MiCombinePageSortByHash);
DmaAdapter = (PADAPTER_OBJECT)KeGetCurrentThread();
v9 = 0i64;
NumOfElements = 0i64;
a3a[1] = (INT64)a3a;
v10 = (unsigned __int64)v61;
v70 = (unsigned __int64)&v61[5 * a3 - 5];
a3a[0] = (INT64)a3a;
if( (unsigned __int64)v61 <= v70 )
{
v11 = DmaAdapter;
while( 1 )
{
PfnDb = MmGetPfnDb();
if( v7 && *(_DWORD *)(v7 + 4) || (*(_DWORD *)&v11[81].Version & 1) != 0 )
{
LABEL_55:
v4 = v63;
v8 = a1a;
goto LABEL_56;
}
CombineProto = 0i64;
v14 = (char *)PfnDb + 48 * *(_QWORD *)(v10 + 8);
v15 = *((_QWORD *)v14 + 1) | 0x8000000000000000ui64;
v16 = (*((_DWORD *)v14 + 4) >> 5) & 0x1F;
if( !(unsigned int)MiValidCombineProtection(v16) || v15 < v20 || v15 > (unsigned __int64)MmGetPteLimit() )
goto LABEL_15;
v21 = *(_MMPTE ***)v10;
if( (v10 == v18 || v21 != *(_MMPTE ***)(v10 + 40)) && (v21 != v17 || v10 == v19) )
{
LODWORD(a5) = 0;
CombineProto = MiAllocateCombineProto(a1a, *(_QWORD *)v10, v16, 0i64, a5);
if( !CombineProto )
goto LABEL_14;
v21 = *(_MMPTE ***)v10;
}
else if( (v14[34] & 0xC0u) >= 0xC0 )
{
*(_QWORD *)v10 = 0i64;
goto LABEL_15;
}
DmaAdapter = 0i64;
v22 = MiCapturePfnVm(
(_MI_PAGE_COMBINING_SUPPORT *)v66,
(_MMPFN *)v14,
(VOID **)(unsigned int)ReferencedObject,
v21,
(UINT *)&DmaAdapter);
if( !v22 || v69 != v15 || v62 != v16 )
{
if( DmaAdapter )
HalPutDmaAdapter(DmaAdapter);
if( CombineProto )
MiDecrementCombinedPte(0i64, (_MMPTE *)(CombineProto + 6));
LABEL_49:
*(_QWORD *)v10 = 0i64;
LABEL_14:
v9 = NumOfElements;
goto LABEL_15;
}
if( !CombineProto )
goto LABEL_23;
v23 = a4a;
if( CombineProto[8] != a4a )
break;
LABEL_24:
*(_DWORD *)(v10 + 32) = v16;
*(_QWORD *)(v10 + 24) = v23;
if( CombineProto )
*(_QWORD *)(v10 + 32) = CombineProto;
v24 = P;
if( !P )
goto LABEL_34;
while( (unsigned __int64)v22 > v24[4] )
{
v24 = (_QWORD *)v24[1];
LABEL_33:
if( !v24 )
goto LABEL_34;
}
if( (unsigned __int64)v22 < v24[4] )
{
v24 = (_QWORD *)*v24;
goto LABEL_33;
}
if( v24 )
{
if( DmaAdapter )
HalPutDmaAdapter(DmaAdapter);
goto LABEL_42;
}
LABEL_34:
LODWORD(v25) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
v24 = v25;
if( !v25 )
{
if( DmaAdapter )
HalPutDmaAdapter(DmaAdapter);
if( CombineProto )
{
MiDecrementCombinedPte(0i64, (_MMPTE *)(CombineProto + 6));
*(_QWORD *)(v10 + 32) = 0i64;
goto LABEL_49;
}
goto LABEL_14;
}
v26 = P;
v27 = 0;
v25[4] = v22;
v25[5] = DmaAdapter;
if( !v26 )
goto LABEL_41;
while( 2 )
{
if( v22 < (_MMSUPPORT_FULL *)(v26 + 4) )
{
v28 = (_QWORD *)*v26;
if( !*v26 )
goto LABEL_41;
goto LABEL_38;
}
v28 = (_QWORD *)v26[1];
if( v28 )
{
LABEL_38:
v26 = v28;
continue;
}
break;
}
v27 = 1;
LABEL_41:
RtlAvlInsertNodeEx((unsigned __int64 *)&P, (__int64)v26, v27, v24);
LABEL_42:
v9 = NumOfElements + 1;
*(_QWORD *)(v10 + 16) = v24[6];
++v24[3];
++NumOfElements;
v24[6] = v10;
*(_QWORD *)(v10 + 8) = (__int64)((v15 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
LABEL_15:
v10 += 40i64;
if( v10 > v70 )
goto LABEL_55;
}
MiDecrementCombinedPte(0i64, (_MMPTE *)(CombineProto + 6));
LODWORD(a5) = 0;
CombineProto = MiAllocateCombineProto(a1a, *(_QWORD *)v10, v16, &a4a, a5);
if( !CombineProto )
{
if( !DmaAdapter )
goto LABEL_49;
HalPutDmaAdapter(DmaAdapter);
*(_QWORD *)v10 = 0i64;
goto LABEL_14;
}
LABEL_23:
v23 = a4a;
goto LABEL_24;
}
LABEL_56:
v29 = 0i64;
if( v9 && (LODWORD(v30) = MiAllocatePool((struct _SLIST_ENTRY *)0x100), (v29 = v30) != 0i64) )
{
v31 = P;
v32 = 0i64;
j = 0i64;
if( P )
{
do
{
j = v31;
v31 = (_QWORD *)*v31;
}
while( v31 );
}
while( j )
{
for( i = j[6]; i; i = *(_QWORD *)(i + 16) )
*(_QWORD *)&v29[4 * v32++] = i;
v35 = (_QWORD **)j[1];
v36 = j;
if( v35 )
{
v37 = *v35;
for( j = (_QWORD *)j[1]; v37; v37 = (_QWORD *)*v37 )
j = v37;
}
else
{
for( j = (_QWORD *)(j[2] & 0xFFFFFFFFFFFFFFFCui64); j; j = (_QWORD *)(j[2] & 0xFFFFFFFFFFFFFFFCui64) )
{
if( (_QWORD *)*j == v36 )
break;
v36 = j;
}
}
}
qsort(v29, NumOfElements, (const WCHAR *)8, MiCombineActiveCrcSortByHash);
v38 = 0i64;
v39 = 0i64;
if( NumOfElements )
{
v40 = (_QWORD **)(v29 + 4);
while( 1 )
{
v41 = *(v40 - 1);
v42 = v41[4];
if( v42 <= 0x100 )
{
if( (v39 && !(unsigned int)MiCompareActiveCrcEntries(*(v40 - 1), *(v40 - 2))
|| v39 != NumOfElements - 1 && !(unsigned int)MiCompareActiveCrcEntries(v41, *v40))
&& v43 )
{
if( v38 && !(unsigned int)MiCompareActiveCrcEntries(v38, v41) )
goto LABEL_79;
LODWORD(a5) = 1;
v54 = MiAllocateCombineProto(v8, *v41, (unsigned int)v42, v41 + 3, a5);
if( !v54 )
goto LABEL_79;
LABEL_110:
if( v54[3] )
{
v41[4] = (UINT64)v54;
}
else
{
MiPushCombineBlock(a3a, v54);
v55 = MiProtectionToCacheAttribute(*((unsigned int *)v41 + 8));
++v72[v55];
}
v38 = v41;
goto LABEL_79;
}
LODWORD(a5) = 0;
v54 = MiAllocateCombineProto(v8, *v41, (unsigned int)v42, v41 + 3, a5);
if( v54 )
goto LABEL_110;
v41[1] = -1i64;
}
LABEL_79:
++v39;
++v40;
if( v39 >= NumOfElements )
{
v4 = v63;
break;
}
}
}
v44 = v66;
MiPopulateCombineMdls(v66, v4, (INT64)v72);
}
else
{
v44 = v66;
}
while( P )
{
v45 = P;
RtlAvlRemoveNode((unsigned __int64 *)&P, (__int64 *)P);
v46 = v45[3];
v47 = v45[6];
if( v29 )
{
if( v47 )
{
v48 = (INT64 *)v29;
do
{
*v48++ = v47;
v47 = *(_QWORD *)(v47 + 16);
}
while( v47 );
}
qsort(v29, v46, (const WCHAR *)8, MiCombineActiveCrcSortByVa);
v45[6] = 0i64;
for( k = 0i64; k < v46; ++k )
{
v50 = *(_QWORD *)&v29[4 * k];
v51 = *(_QWORD *)(v50 + 8);
if( v51 == -1 || k && v51 == *(_QWORD *)(*(_QWORD *)&v29[4 * k - 4] + 8i64) )
{
MiDereferenceCombineCrc(v50);
--v45[3];
}
else
{
*(_QWORD *)(v50 + 16) = v45[6];
v45[6] = v50;
}
}
if( v45[3] )
{
LODWORD(a5) = v4;
MiSharePages(v44, v45, a3a, &v71, a5);
}
}
else
{
for( ; v47; v47 = *(_QWORD *)(v47 + 16) )
MiDereferenceCombineCrc(v47);
}
v52 = (struct _DMA_ADAPTER *)v45[5];
if( v52 )
HalPutDmaAdapter(v52);
ExFreePoolWithTag(v45, 0);
}
if( v29 )
ExFreePoolWithTag(v29, 0);
if( (*(_DWORD *)(v44 + 60) & 2) == 0 )
MiFreeCombineMdls(v44);
while( 1 )
{
v53 = a3a[0];
result = a3a;
if( (INT64 *)a3a[0] == a3a )
break;
if( *(INT64 **)(a3a[0] + 8) != a3a || (v56 = *(_QWORD *)a3a[0], *(_QWORD *)(*(_QWORD *)a3a[0] + 8i64) != a3a[0]) )
__fastfail(3u);
a3a[0] = *(_QWORD *)a3a[0];
*(_QWORD *)(v56 + 8) = a3a;
*(_QWORD *)(v53 + 32) = 0i64;
MiFreeCombineBlock(v53);
}
}
return result;
}Referenced by:
MiCombineAllPhysicalMemory
MiCombineWorkingSetTail