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