MiAllocateCombineProto
_MI_COMBINE_BLOCK *__stdcall MiAllocateCombineProto(
_MI_PAGE_COMBINING_SUPPORT *Pcs,
UINT64 HashValue,
UINT64 ProtectionMask,
UINT64 AllocateNewEntryIfNeeded){
unsigned int v5;
unsigned __int64 inserted;
UINT64 v9;
INT64 *p_Lock;
unsigned __int64 v11;
_RTL_BALANCED_NODE *Root;
int v13;
unsigned int v15;
signed __int64 v16;
signed __int64 v17;
_MI_PAGE_COMBINING_SUPPORT *Flink;
_LIST_ENTRY *p_CombinePageFreeList;
_LIST_ENTRY *Partition;
int v21;
_MI_COMBINE_BLOCK *Pool;
UINT64 v23;
_MI_COMBINE_BLOCK *v24;
_KLOCK_QUEUE_HANDLE LockHandle;
UINT64 v26;
unsigned int v27;
int v28;
UINT64 v29;
int v30;
v5 = ProtectionMask;
memset(&LockHandle, 0, sizeof(LockHandle));
if( !HashValue )
return 0i64;
inserted = 0i64;
v9 = HashValue & 0xF;
p_Lock = (INT64 *)&Pcs->CombinePageListHeads[v9].Lock;
v11 = (unsigned __int8)ExAcquireSpinLockShared(p_Lock);
v28 = 0;
v26 = HashValue;
v27 = v5;
v29 = AllocateNewEntryIfNeeded;
Root = Pcs->CombinePageListHeads[v9].Table.Root;
if( !Root )
{
LABEL_8:
v13 = v30;
goto LABEL_9;
}
while( 1 )
{
if( (_RTL_BALANCED_NODE *)HashValue > Root[1].Children[0] )
{
LABEL_6:
Root = Root->Children[1];
goto LABEL_7;
}
if( (_RTL_BALANCED_NODE *)HashValue >= Root[1].Children[0] )
{
v15 = *(_DWORD *)&Root[1]._bf_0 & 0x1F;
if( v5 >= v15 )
{
if( v5 > v15 )
goto LABEL_6;
if( !AllocateNewEntryIfNeeded )
break;
if( *(_QWORD *)AllocateNewEntryIfNeeded > Root[2].ParentValue )
goto LABEL_6;
if( *(_QWORD *)AllocateNewEntryIfNeeded >= Root[2].ParentValue )
break;
}
}
Root = Root->Children[0];
LABEL_7:
if( !Root )
goto LABEL_8;
}
v16 = (signed __int64)Root[1].Children[1];
if( !v16 )
{
LABEL_30:
v13 = 0;
LABEL_9:
_InterlockedAnd((volatile signed __int32 *)p_Lock, 0xBFFFFFFF);
_InterlockedDecrement((volatile signed __int32 *)p_Lock);
__writecr8(v11);
if( !v13 )
return 0i64;
KeAcquireInStackQueuedSpinLock(&Pcs->CombineFreeListLock, &LockHandle);
Flink = (_MI_PAGE_COMBINING_SUPPORT *)Pcs->CombinePageFreeList.Flink;
p_CombinePageFreeList = &Pcs->CombinePageFreeList;
if( Flink != (_MI_PAGE_COMBINING_SUPPORT *)&Pcs->CombinePageFreeList )
{
inserted = (unsigned __int64)Pcs->CombinePageFreeList.Flink;
Partition = (_LIST_ENTRY *)Flink->Partition;
if( *(_LIST_ENTRY **)(inserted + 8) != p_CombinePageFreeList || Partition->Blink != (_LIST_ENTRY *)inserted )
__fastfail(3u);
p_CombinePageFreeList->Flink = Partition;
Partition->Blink = p_CombinePageFreeList;
++*(_DWORD *)((inserted & 0xFFFFFFFFFFFFF000ui64) + 8);
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
if( !inserted )
{
Pool = (_MI_COMBINE_BLOCK *)MiAllocatePool(274i64, 0x1000ui64, 0x6D75534Dui64);
v24 = Pool;
if( !Pool )
return 0i64;
Pool[2] = 1;
*((_QWORD *)Pool + 2) = Pcs;
inserted = (unsigned __int64)MiInsertNewCombineBlocks(Pcs, Pool + 18, v23);
if( !inserted )
{
ExFreePoolWithTag(v24, 0);
return 0i64;
}
}
_InterlockedExchangeAdd(&Pcs->PageCombineStats.CombinedBlocksInUse, 1u);
v21 = (*(_DWORD *)(inserted + 40) ^ v5) & 0x1F;
*(_QWORD *)(inserted + 32) = 1i64;
*(_DWORD *)(inserted + 40) ^= v21;
*(_QWORD *)(inserted + 64) = *(_QWORD *)AllocateNewEntryIfNeeded;
_InterlockedExchangeAdd(&Pcs->PageCombineStats.SumCombinedBlocksReferenceCount, 1u);
return(_MI_COMBINE_BLOCK *)inserted;
}
while( 1 )
{
v17 = v16;
v16 = _InterlockedCompareExchange64((volatile signed __int64 *)&Root[1].Children[1], v16 + 1, v16);
if( v17 == v16 )
break;
if( !v16 )
goto LABEL_30;
}
ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)p_Lock);
__writecr8(v11);
_InterlockedExchangeAdd(&Pcs->PageCombineStats.SumCombinedBlocksReferenceCount, 1u);
return(_MI_COMBINE_BLOCK *)Root;
}Referenced by:
MiProcessCrcList
MiSharePages