RtlpInsertFreeBlock
VOID __stdcall RtlpInsertFreeBlock(_HEAP *Heap, _HEAP_FREE_ENTRY *FreeBlock, UINT64 FreeSize){
_HEAP_FREE_ENTRY *v3;
UINT64 v4;
__int64 PreviousSize;
INT64 v7;
__int64 SegmentOffset;
_HEAP *v9;
unsigned __int8 Flags;
_LIST_ENTRY *p_FreeLists;
unsigned __int16 v12;
unsigned __int8 v13;
_HEAP *v14;
unsigned __int64 v15;
_HEAP_FREE_ENTRY *v16;
unsigned __int64 v17;
_LIST_ENTRY *Entry;
unsigned int EncodeFlagMask;
int Blink;
unsigned __int16 v21;
VOID **p_Flink;
_LIST_ENTRY *p_FreeList;
_HEAP_LIST_LOOKUP *BlocksIndex;
unsigned __int64 i;
_HEAP_LIST_LOOKUP *ExtendedLookup;
int Size;
VOID *Param2;
unsigned int v29;
unsigned __int8 v30;
if( FreeSize )
{
v3 = FreeBlock;
PreviousSize = FreeBlock->HeapEntry.UnpackedEntry.PreviousSize;
v4 = FreeSize;
LOWORD(PreviousSize) = Heap->Encoding.UnpackedEntry.PreviousSize ^ PreviousSize;
if( !(_WORD)PreviousSize
&& RtlpHeapErrorHandlerThreshold >= 1
&& (v3->HeapEntry.UnpackedEntry.Flags & 8) == 0
&& (_HEAP_FREE_ENTRY *)(((unsigned __int64)&v3[127].FreeList.Blink + 7) & 0xFFFFFFFFFFFFF000ui64) != v3 )
{
DbgPrint(
"((FreeBlock->Flags & HEAP_ENTRY_DECOMMITTED) || (ROUND_UP_TO_POWER2(FreeBlock, PAGE_SIZE) == (ULONG_PTR)FreeBlock))",
PreviousSize,
FreeSize,
0i64);
RtlpHeapHandleError(v7);
}
SegmentOffset = v3->HeapEntry.UnpackedEntry.SegmentOffset;
if( (_BYTE)SegmentOffset )
v9 = (_HEAP *)(((unsigned __int64)v3 & 0xFFFFFFFFFFFF0000ui64) - (SegmentOffset << 16) + 0x10000);
else
v9 = Heap;
Flags = v3->HeapEntry.UnpackedEntry.Flags;
p_FreeLists = &Heap->FreeLists;
v30 = Flags;
while( 1 )
{
if( v4 <= 0xFF00 )
{
v12 = v4;
}
else
{
v12 = -272;
if( v4 != 65281 )
v12 = -256;
}
v13 = 0;
if( v4 <= 0xFF00 )
v13 = Flags;
v3->HeapEntry.UnpackedEntry.Flags = v13;
v3->HeapEntry.UnpackedEntry.PreviousSize = PreviousSize ^ Heap->Encoding.UnpackedEntry.PreviousSize;
v14 = v9->Segment.Heap;
if( v14 == v9 )
{
LOBYTE(v15) = 0;
}
else
{
v15 = ((unsigned __int64)((char *)v3 - (char *)v9) >> 16) + 1;
if( v15 >= 0xFE )
RtlpLogHeapFailure(heap_failure_entry_corruption, v14, v3, v9, 0i64);
}
v3->HeapEntry.UnpackedEntry.Flags &= 0xF0u;
v3->HeapEntry.UnpackedEntry.SegmentOffset = v15;
v3->HeapEntry.UnpackedEntry.Size = v12;
v3->HeapEntry.UnpackedEntry.SmallTagIndex = 0;
v3->HeapEntry.UnpackedEntry.UnusedBytes = 0;
if( (Heap->Flags & 0x40) != 0 )
{
v16 = v3 + 1;
v17 = (16 * (unsigned __int64)v12 - 32) >> 2;
if( v17 )
{
if( ((unsigned __int8)v16 & 4) != 0 )
{
--v17;
LODWORD(v16->HeapEntry.UnpackedEntry.PreviousBlockPrivateData) = -17891602;
v16 = (_HEAP_FREE_ENTRY *)((char *)v3 + 36);
}
memset64(v16, 0xFEEEFEEEFEEEFEEEui64, v17 >> 1);
if( (v17 & 1) != 0 )
*((_DWORD *)&v16->HeapEntry.UnpackedEntry + v17 - 1) = -17891602;
}
v3->HeapEntry.UnpackedEntry.Flags |= 4u;
}
if( Heap->BlocksIndex )
Entry = RtlpFindEntry(Heap, v12);
else
Entry = p_FreeLists->Flink;
if( p_FreeLists != Entry )
{
EncodeFlagMask = Heap->EncodeFlagMask;
do
{
if( EncodeFlagMask )
{
Blink = (int)Entry[-1].Blink;
EncodeFlagMask = Heap->EncodeFlagMask;
LOWORD(v29) = Blink;
if( (EncodeFlagMask & Blink) != 0 )
v29 = Heap->Encoding.UnpackedEntry.SubSegmentCode ^ Blink;
v21 = v29;
}
else
{
v21 = (unsigned __int16)Entry[-1].Blink;
}
if( v12 <= (unsigned __int64)v21 )
break;
Entry = Entry->Flink;
}
while( p_FreeLists != Entry );
}
p_Flink = (VOID **)&Entry->Blink->Flink;
p_FreeList = &v3->FreeList;
if( *p_Flink == Entry )
{
p_FreeList->Flink = Entry;
v3->FreeList.Blink = (_LIST_ENTRY *)p_Flink;
*p_Flink = p_FreeList;
Entry->Blink = p_FreeList;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, Entry, 0i64, *p_Flink);
}
Heap->TotalFreeSize += v3->HeapEntry.UnpackedEntry.Size;
BlocksIndex = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( BlocksIndex )
{
for( i = BlocksIndex->ArraySize; ; i = ExtendedLookup->ArraySize )
{
if( v3->HeapEntry.UnpackedEntry.Size < i )
{
Size = v3->HeapEntry.UnpackedEntry.Size;
goto LABEL_50;
}
ExtendedLookup = BlocksIndex->ExtendedLookup;
if( !BlocksIndex->ExtendedLookup )
break;
BlocksIndex = BlocksIndex->ExtendedLookup;
}
Size = BlocksIndex->ArraySize - 1;
LABEL_50:
LODWORD(Param2) = Size;
RtlpHeapAddListEntry(Heap, BlocksIndex, Entry, (UINT64)&v3->FreeList, (UINT64)Param2);
}
if( Heap->EncodeFlagMask )
{
v3->HeapEntry.UnpackedEntry.SmallTagIndex = LOBYTE(v3->InterceptorValue) ^ BYTE1(v3->Code1) ^ v3->HeapEntry.UnpackedEntry.Flags;
v3->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
}
v4 -= v12;
LOWORD(PreviousSize) = v12;
v3 = (_HEAP_FREE_ENTRY *)((char *)v3 + 16 * v12);
if( (_HEAP_ENTRY *)v3 >= v9->Segment.LastValidEntry )
break;
Flags = v30;
p_FreeLists = &Heap->FreeLists;
if( !v4 )
{
v3->HeapEntry.UnpackedEntry.PreviousSize = v12 ^ Heap->Encoding.UnpackedEntry.PreviousSize;
return;
}
}
}
}Referenced by:
RtlpCreateSplitBlock
RtlpDeCommitFreeBlock
RtlpExtendHeap
RtlpFreeHeap
RtlpInitializeHeapSegment