RtlpHpLargeAlloc
NTSTATUS __stdcall RtlpHpLargeAlloc(INT64 a1, INT16 a2, UINT64 r8_0, CHAR r9_0){
__int128 v4;
NTSTATUS v5;
_OWORD *v8;
int v9;
unsigned int v10;
__int64 v11;
UINT64 v12;
int v13;
int v14;
char v15;
int v16;
unsigned __int64 v17;
UINT64 v18;
unsigned __int64 v19;
UINT8 v20;
UINT64 *v21;
unsigned __int64 v22;
UINT64 v23;
BOOL v24;
UINT64 v25;
INT64 v26;
_ETHREAD *CurrentThread;
unsigned int SessionId;
unsigned __int8 v30;
int v31;
bool v32;
__int64 v33;
_KLOCK_ENTRY *v34;
__int64 v35;
PVOID BugCheckParameter4;
PVOID BugCheckParameter4a;
INT64 v38;
__int64 v39;
UINT64 a3;
__int64 v41;
INT64 *v42;
UINT64 a4;
__int128 a4_8;
__int128 v45;
__int128 v46;
__int64 v47[2];
__int128 v48;
__int128 v49;
__int128 v50;
__int128 v51;
__int128 v52;
__int128 v53;
__int128 v54;
__int128 v55;
__int128 v56;
UINT64 v57;
v4 = *(_OWORD *)a1;
v39 = 0i64;
LODWORD(v41) = 0;
v5 = 0;
v42 = 0i64;
HIDWORD(a3) = 0;
v38 = 0i64;
a4_8 = v4;
v8 = RtlpHpMetadataAlloc((VOID *)0x28, 0x28ui64, 0i64);
if( v8 )
{
*v8 = 0i64;
v9 = 0;
v8[1] = 0i64;
*((_QWORD *)v8 + 4) = 0i64;
if( (*(_DWORD *)(a1 + 20) & 0x4000000) != 0 && 0x1FFFFF - ((r8_0 - 1) & 0x1FFFFF) < r8_0 >> 2 )
v9 = 1;
while( 1 )
{
v10 = 0;
if( v9 )
{
v11 = 0x200000i64;
v12 = r8_0 - ((r8_0 - 1) & 0x1FFFFF) + 0x1FFFFF;
}
else
{
LOBYTE(v10) = BYTE1(*(_QWORD *)a1) < 2u;
v11 = 0i64;
v12 = r8_0 + (v10 << 12);
}
v39 = v12;
if( v12 < r8_0 )
break;
v13 = *(_DWORD *)(a1 + 20) & 0x40000000;
v45 = *(_OWORD *)a1;
v51 = 0i64;
v52 = 0i64;
v53 = 0i64;
if( v13 )
{
*(_QWORD *)&v51 = a1;
DWORD2(v51) = 64;
}
LODWORD(BugCheckParameter4) = v13 != 0 ? 64 : 4;
if( RtlpHpAllocVA(&v38, &v39, v11, 0x2000, (UINT64)BugCheckParameter4, (__int64)&v45) < 0 )
{
v38 = 0i64;
break;
}
v46 = *(_OWORD *)a1;
RtlpHpQueryVA(v38, &v46, &v42, (_DWORD *)&a3 + 1);
*v42 = a1;
v57 = (r8_0 + 4095) >> 12;
a4 = v57 << 12;
if( !RtlpHpSegHeapCheckCommitLimit(v57 << 12, (UINT64 *)a1) )
break;
if( v9 )
{
v14 = 536875008;
a4 = (v57 << 12) - (((v57 << 12) - 1) & 0x1FFFFF) + 0x1FFFFF;
v15 = r9_0;
}
else
{
v15 = r9_0;
v14 = 4096;
if( (r9_0 & 2) != 0 )
v14 = 1073745920;
}
v16 = *(_DWORD *)(a1 + 20) & 0x40000000;
*(_OWORD *)v47 = *(_OWORD *)a1;
v54 = 0i64;
v55 = 0i64;
v56 = 0i64;
if( v16 )
{
*(_QWORD *)&v54 = a1;
DWORD2(v54) = 64;
}
LODWORD(BugCheckParameter4a) = v16 != 0 ? 64 : 4;
if( RtlpHpAllocVA(&v38, (__int64 *)&a4, 0i64, v14, (UINT64)BugCheckParameter4a, (__int64)v47) >= 0 )
{
if( v9 && (v15 & 2) != 0 )
memset((VOID *)v38, 0i64, r8_0);
v17 = (r8_0 + 4095) >> 12;
*((_QWORD *)v8 + 3) = v38;
v18 = v8[2] & 0xFFD | (2 * (v10 | (v57 << 11)));
*((_QWORD *)v8 + 4) = v18;
_BitScanForward64(&v19, v39);
LODWORD(v41) = v19;
*((_QWORD *)v8 + 4) = v18 ^ (unsigned __int8)(v18 ^ (4 * v19)) & 0xFC;
*((_WORD *)v8 + 12) = ((_WORD)v57 << 12) - a2;
v20 = RtlpHpLargeLockAcquire(a1, v15);
v21 = (UINT64 *)(a1 + 72);
v22 = v20;
if( (*(_BYTE *)(a1 + 80) & 1) != 0 )
{
if( *v21 )
v23 = *v21 ^ (unsigned __int64)v21;
else
v23 = 0i64;
}
else
{
v23 = *v21;
}
v24 = 0;
if( v23 )
{
while( 1 )
{
if( v38 < (*(_QWORD *)(v23 + 24) & 0xFFFFFFFFFFFF0000ui64) )
{
v25 = *(_QWORD *)v23;
if( (*(_BYTE *)(a1 + 80) & 1) != 0 )
{
if( !v25 )
break;
v25 ^= v23;
}
if( !v25 )
break;
}
else
{
v25 = *(_QWORD *)(v23 + 8);
if( (*(_BYTE *)(a1 + 80) & 1) != 0 )
{
if( !v25 )
goto LABEL_34;
v25 ^= v23;
}
if( !v25 )
{
LABEL_34:
v24 = 1;
break;
}
}
v23 = v25;
}
}
RtlRbInsertNodeEx(v21, v23, v24, (UINT64)v8);
if( (v15 & 1) == 0 )
{
v26 = a1 + 64;
if( (*(_DWORD *)a1 & 1) != 0 )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(a1 + 64));
__writecr8(v22);
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v26, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)(a1 + 64));
LODWORD(a3) = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType(a1 + 64) == 1 )
SessionId = MmGetSessionIdEx(CurrentThread->Tcb.ApcState.Process);
else
SessionId = -1;
--CurrentThread->Tcb.SpecialApcDisable;
v30 = ++CurrentThread->Tcb.AbAllocationRegionCount;
v31 = ((char)CurrentThread->Tcb.AbEntrySummary | (char)CurrentThread->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
while( 1 )
{
v32 = !_BitScanReverse((unsigned int *)&v33, v31);
if( v32 )
break;
v34 = &CurrentThread->Tcb.LockEntries[v33];
v31 &= ~(1 << v33);
if( (v34->AcquiredByte & 1) != 0
&& (v34->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v34->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v26 & 0x7FFFFFFFFFFFFFFCi64)
&& v34->LockState.SessionId == SessionId )
{
v34->AcquiredByte &= ~1u;
if( v34->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
{
if( v34 )
{
v34->CrossThreadReleasableAndBusyByte |= 2u;
if( v34->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v34);
LODWORD(a3) = v34->BoostBitmap.AllFields & 0x1FFFF;
v34->BoostBitmap.AllFields &= 0xFFFE0000;
v34->ThreadLocalFlags &= ~1u;
v34->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v35 = v34 - CurrentThread->Tcb.LockEntries;
if( v30 == 1 )
CurrentThread->Tcb.AbEntrySummary |= 1 << v35;
else
_InterlockedOr8((volatile signed __int8 *)&CurrentThread->Tcb.AbOrphanedEntrySummary, 1 << v35);
goto LABEL_67;
}
break;
}
}
}
if( (*(&CurrentThread->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, CurrentThread, (PVOID)(a1 + 64), (PVOID)SessionId, 0i64);
LABEL_67:
--CurrentThread->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&CurrentThread->Tcb, (VOID *)(a1 + 64), &a3);
v32 = CurrentThread->Tcb.SpecialApcDisable++ == -1;
if( v32
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152 )
{
KiCheckForKernelApcDelivery();
}
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
}
}
_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 88), v39 / 4096);
_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 96), v17);
v5 = v38;
v8 = 0i64;
v38 = 0i64;
break;
}
if( !v9 )
break;
v9 = 0;
v48 = *(_OWORD *)a1;
RtlpHpFreeVA((UINT64 *)&v38, (UINT64 *)&v39, 0x8000i64, &v48);
v38 = 0i64;
}
if( v8 )
{
v49 = *(_OWORD *)a1;
RtlpHpMetadataFree((__int64)v8, &v49);
}
}
if( v38 )
{
v50 = *(_OWORD *)a1;
RtlpHpFreeVA((UINT64 *)&v38, (UINT64 *)&v39, 0x8000i64, &v50);
}
return v5;
}Referenced by:
ExAllocateHeapPool
RtlpHpAllocateHeapInternal