MiAllocatePerSessionProtos

__int64 __fastcall MiAllocatePerSessionProtos(
        __int64 a1,
        unsigned __int64 a2,
        unsigned int a3,
        __int64 a4,
        __int64 **a5){
  _MDL *v6; 
  RTL_BALANCED_NODE *v7; 
  _MI_PARTITION *ControlAreaPartition; 
  __int64 v9; 
  __int64 *v10; 
  INT64 v11; 
  _QWORD *v12; 
  INT64 SubsectionPte; 
  RTL_BALANCED_NODE *v14; 
  INT64 v15; 
  unsigned int v16; 
  unsigned int v17; 
  INT64 v18; 
  int v19; 
  unsigned __int64 v20; 
  unsigned __int64 v21; 
  _MMPTE *v22; 
  int v23; 
  unsigned __int64 v25; 
  _MDL *v26; 
  int v27; 
  _CONTROL_AREA *v28; 
  int v29; 
  void *v30; 
  unsigned int NumberOfPtes; 
  _MI_PARTITION *Partition; 
  RTL_BALANCED_NODE *Node; 
  INT64 v34; 
  _CONTROL_AREA *ControlArea; 
  __int64 *v36; 
  *a5 = 0i64;
  v6 = 0i64;
  v7 = 0i64;
  ControlArea = *(_CONTROL_AREA **)a1;
  ControlAreaPartition = MiGetControlAreaPartition(*(_CONTROL_AREA **)a1);
  Partition = ControlAreaPartition;
  if( !(unsigned int)MiChargeCommit(ControlAreaPartition, *(unsigned int *)(a1 + 44), 0i64) )
    return 3221225773i64;
  LODWORD(v9) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
  v10 = (__int64 *)v9;
  v36 = (__int64 *)v9;
  if( !v9 )
  {
    v23 = -1073741670;
    goto LABEL_17;
  }
  *(_DWORD *)(v9 + 80) = 1;
  LODWORD(v11) = MiAllocatePool((struct _SLIST_ENTRY *)0x112);
  v12 = (_QWORD *)v11;
  if( !v11 )
  {
    v23 = -1073741670;
    goto LABEL_16;
  }
  v10[9] = v11;
  memset(v11, 0i64);
  SubsectionPte = MiMakeSubsectionPte(a1);
  v14 = (RTL_BALANCED_NODE *)(v10 + 3);
  Node = (RTL_BALANCED_NODE *)(v10 + 3);
  v10[6] = v10[6] & 0xFFFFFFFFFFFFFFF8ui64 | 3;
  v15 = *(_QWORD *)(a1 + 8);
  v34 = v15;
  v16 = 0;
  NumberOfPtes = 0;
  if( *(_DWORD *)(a1 + 44) )
  {
    v17 = 0;
    do
    {
      v18 = MI_READ_PTE_LOCK_FREE(v15);
      if( !v18 )
        break;
      if( !a2 )
      {
        MiPteInShadowRange((UINT64)v12);
        if( IS_PTE_NOT_DEMAND_ZERO(v18) )
        {
          v20 = SubsectionPte;
          if( v19
            && (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0
            && (SubsectionPte & 1) != 0 )
          {
            v20 = SubsectionPte | 0x8000000000000000ui64;
          }
          *v12 = v20;
        }
        else
        {
          if( v19 && (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0 && (v18 & 1) != 0 )
            v18 |= 0x8000000000000000ui64;
          *v12 = v18;
        }
      }
      ++v12;
      v15 = v34 + 8;
      v34 += 8i64;
      ++v17;
    }
    while( v17 < *(_DWORD *)(a1 + 44) );
    NumberOfPtes = v17;
    v10 = v36;
    v6 = 0i64;
    v14 = Node;
    v16 = NumberOfPtes;
  }
  v21 = v16;
  v10[7] = v16;
  MiUpdateSystemProtoPtesTree(v14, 1i64);
  v22 = (_MMPTE *)v10[9];
  if( a2 )
  {
    v25 = v21 << 12;
    MmSizeOfMdl((PVOID)a2, v21 << 12);
    LODWORD(v26) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
    v6 = v26;
    if( !v26 )
      goto LABEL_40;
    v26->Next = 0i64;
    v26->Size = 8 * (((v25 + (a2 & 0xFFF) + 4095) >> 12) + 6);
    v26->MdlFlags = 0;
    v26->StartVa = (void *)(a2 & 0xFFFFFFFFFFFFF000ui64);
    v26->ByteOffset = a2 & 0xFFF;
    v26->ByteCount = v25;
    MmProbeAndLockPages(v26, 0, IoReadAccess);
    v27 = (*(unsigned __int16 *)(a1 + 32) >> 1) & 0x1F;
    if( !(unsigned int)MiChargeResident((ULONG_PTR *)Partition, v21, 0i64) )
    {
LABEL_40:
      v23 = -1073741670;
      goto LABEL_15;
    }
    if( (MiFlags & 0x10000) != 0 && (MiFlags & 0x8000) != 0 && (v27 & 2) != 0 )
      v28 = ControlArea;
    else
      v28 = ControlArea;
    MiFillPerSessionProtos(v28, v22, (UINT64 *)&v6[1], NumberOfPtes);
    v23 = v29;
    if( v29 < 0 )
      goto LABEL_15;
  }
  *a5 = v10;
  v10 = 0i64;
  v23 = 0;
LABEL_15:
  v7 = Node;
LABEL_16:
  ControlAreaPartition = Partition;
LABEL_17:
  if( v6 )
  {
    MmUnlockPages(v6);
    ExFreePoolWithTag(v6, 0);
  }
  if( v10 )
  {
    if( v7 )
      MiUpdateSystemProtoPtesTree(v7, 0i64);
    v30 = (void *)v10[9];
    if( v30 )
      ExFreePoolWithTag(v30, 0);
    ExFreePoolWithTag(v10, 0);
  }
  if( v23 < 0 )
    MiReturnCommit(ControlAreaPartition, *(unsigned int *)(a1 + 44));
  return(unsigned int)v23;
}

Referenced by:

MiCreatePerSessionProtos
MiCreateSessionDriverProtos