MiBuildNewCloneDescriptor

_MMCLONE_DESCRIPTOR *__stdcall MiBuildNewCloneDescriptor(
        ULONG_PTR CurrentProcess,
        UINT64 NumberOfPrivatePages,
        UINT64 NestingLevel){
  UINT64 v4; 
  _EPROCESS *v6; 
  UINT64 v7; 
  _MMCLONE_DESCRIPTOR *Pool; 
  _OWORD *v10; 
  INT64 v11; 
  _MMCLONE_HEADER *v12; 
  void *v13; 
  _EPROCESS *v14; 
  _MI_PARTITION *VmPartition; 

  v4 = 32 * NumberOfPrivatePages;
  v6 = *(_EPROCESS **)&CurrentProcess;
  v7 = 32 * NumberOfPrivatePages + 32;
  if( PsChargeProcessNonPagedPoolQuota(*(_EPROCESS **)&CurrentProcess, v7) < 0 )
    return 0i64;
  Pool = (_MMCLONE_DESCRIPTOR *)MiAllocatePool(64i64, 0x70ui64, 0x64436D4Dui64);
  if( !Pool )
  {
    PsReturnProcessNonPagedPoolQuota(v6, v7);
    return 0i64;
  }
  v10 = MiAllocatePool(274i64, v7, 0x6C436D4Dui64);
  v11 = (INT64)v10;
  if( !v10 )
  {
LABEL_6:
    PsReturnProcessNonPagedPoolQuota(v6, v7);
    ExFreePoolWithTag(Pool, 0);
    return 0i64;
  }
  *v10 = 0i64;
  v10[1] = 0i64;
  v12 = (_MMCLONE_HEADER *)MiAllocatePool(64i64, 0x20ui64, 0x68436D4Dui64);
  v13 = (void *)v11;
  if( !v12 )
  {
LABEL_8:
    ExFreePoolWithTag(v13, 0);
    goto LABEL_6;
  }
  if( !MiLockPagedRange(v11, v7) )
  {
    ExFreePoolWithTag(v12, 0);
    v13 = (void *)v11;
    goto LABEL_8;
  }
  VmPartition = MiGetVmPartition(&v6->Vm, v14);
  v12->NumberOfPtes = NumberOfPrivatePages;
  v12->NumberOfProcessReferences = 1i64;
  v12->ClonePtes = (_MMCLONE_BLOCK *)v11;
  Pool->NumberOfReferences = 0i64;
  Pool->EndingCloneBlock = (_MMCLONE_BLOCK *)(v11 + v4 - 32);
  Pool->StartingCloneBlock = (_MMCLONE_BLOCK *)v11;
  Pool->NumberOfPtes = NumberOfPrivatePages;
  Pool->CloneHeader = v12;
  Pool->NonPagedPoolQuotaCharge = v7;
  Pool->NestingLevel = NestingLevel;
  _InterlockedIncrement64(&VmPartition->Segments.CloneHeaderCount);
  v12->Partition = VmPartition;
  return Pool;
}

Referenced by:

MiCloneProcessAddressSpace
MiCloneVads