RtlpFindAndCommitPages
_HEAP_FREE_ENTRY *__stdcall RtlpFindAndCommitPages(_HEAP *Heap, UINT64 *Size){
_HEAP *UCREntry;
_HEAP *v5;
INT64 v6;
_HEAP_TUNING_PARAMETERS *p_TuningParameters;
char v8;
__int64 v9;
_HEAP *v10;
int v11;
_HEAP_UCR_DESCRIPTOR *v12;
VOID *v13;
UINT64 v15;
UINT64 v16;
_HEAP *v17;
UINT64 AllocationType;
UINT64 Protect;
VOID *BaseAddress;
UCREntry = (_HEAP *)RtlpFindUCREntry(Heap, *Size);
v5 = UCREntry;
if( UCREntry == (_HEAP *)&Heap->UCRList )
return 0i64;
if( RtlpHeapErrorHandlerThreshold >= 1 && UCREntry->Segment.Heap < (_HEAP *)*Size )
{
DbgPrint("(UCRBlock->Size >= *Size)");
RtlpHeapHandleError(v6);
}
p_TuningParameters = &UCREntry[-1].TuningParameters;
v8 = 0;
v9 = BYTE6(UCREntry[-1].TuningParameters.MaxPreCommittThreshold);
if( (_BYTE)v9 )
v10 = (_HEAP *)(((unsigned __int64)p_TuningParameters & 0xFFFFFFFFFFFF0000ui64) - (v9 << 16) + 0x10000);
else
v10 = Heap;
BaseAddress = v5->Segment.SegmentListEntry.Blink;
if( (int(__fastcall *)(void *, void **, unsigned __int64 *))RtlpHeapKey != Heap->CommitRoutine )
{
v11 = ((__int64(__fastcall *)(_HEAP *, VOID **, UINT64 *))(RtlpHeapKey ^ (__int64)Heap->CommitRoutine))(
Heap,
&BaseAddress,
Size);
}
else
{
v13 = (VOID *)((*Size + 4095) & 0xFFFFFFFFFFFFF000ui64);
*Size = (UINT64)v13;
if( RtlpHpHeapCheckCommitLimit(
v13,
Heap->Counters.TotalMemoryCommitted - Heap->Counters.InBlockDeccomitSize,
Heap,
(INT8 *)&Heap->CommitLimitData) )
{
LODWORD(Protect) = 4;
LODWORD(AllocationType) = 4096;
ZwAllocateVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, 0i64, Size, AllocationType, Protect);
}
RtlpUpdateHeapRates(Heap, 2ui64);
}
if( v11 < 0 )
{
++Heap->Counters.CommitFailures;
return 0i64;
}
if( Heap->EncodeFlagMask )
{
LODWORD(p_TuningParameters->MaxPreCommittThreshold) ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
LOBYTE(v12) = LOBYTE(p_TuningParameters->MaxPreCommittThreshold) ^ BYTE1(p_TuningParameters->MaxPreCommittThreshold) ^ BYTE2(p_TuningParameters->MaxPreCommittThreshold);
if( BYTE3(p_TuningParameters->MaxPreCommittThreshold) != (_BYTE)v12 )
RtlpAnalyzeHeapFailure(Heap, (_HEAP_ENTRY *)p_TuningParameters);
}
BYTE2(p_TuningParameters->MaxPreCommittThreshold) = 0;
HIBYTE(p_TuningParameters->MaxPreCommittThreshold) = 0;
RtlpRemoveUCRBlock(v12);
--v10->Segment.NumberOfUnCommittedRanges;
v10->Segment.NumberOfUnCommittedPages -= (unsigned __int64)v5->Segment.Heap >> 12;
Heap->Counters.TotalMemoryCommitted += (unsigned __int64)v5->Segment.Heap;
++Heap->Counters.CommittOps;
--Heap->Counters.TotalUCRs;
v15 = (UINT64)v5->Segment.Heap;
if( v15 >= 0xFF000 )
{
Heap->Counters.TotalMemoryLargeUCR -= v15;
v15 = (UINT64)v5->Segment.Heap;
}
v16 = *Size;
if( v15 > *Size || (char *)v5->Segment.SegmentListEntry.Blink + v15 == (char *)v10->Segment.LastValidEntry )
{
RtlpCreateUCREntry(
Heap,
&v10->Segment,
(_HEAP_UCR_DESCRIPTOR *)((char *)&v5->Segment.SegmentListEntry.Blink[-3] + v16),
v15 - v16,
(_HEAP_FREE_ENTRY *)p_TuningParameters,
Size);
*Size *= 16i64;
}
else
{
*Size = v16 + 16i64 * LOWORD(p_TuningParameters->MaxPreCommittThreshold);
}
BYTE3(p_TuningParameters->MaxPreCommittThreshold) = 0;
v17 = v10->Segment.Heap;
if( v17 != v10 )
{
if( ((unsigned __int64)((char *)p_TuningParameters - (char *)v10) >> 16) + 1 >= 0xFE )
RtlpLogHeapFailure(heap_failure_entry_corruption, v17, p_TuningParameters, v10, 0i64);
v8 = ((unsigned int)((_DWORD)p_TuningParameters - (_DWORD)v10) >> 16) + 1;
}
BYTE6(p_TuningParameters->MaxPreCommittThreshold) = v8;
return(_HEAP_FREE_ENTRY *)p_TuningParameters;
}Referenced by:
RtlpExtendHeap