RtlpHpVsChunkSplit
NTSTATUS __stdcall RtlpHpVsChunkSplit(ULONG_PTR SpinLock, UINT64 a2, INT64 a3, UINT64 a4, INT64 a5, INT64 a6){
unsigned int v7;
INT64 v8;
unsigned int v9;
__int64 v11;
unsigned int v12;
unsigned int v13;
unsigned int v14;
int v15;
unsigned __int64 v16;
int v17;
int v18;
int v19;
int v20;
int v21;
bool v22;
unsigned int v23;
unsigned __int64 v24;
unsigned __int64 v25;
__int64 v26;
int v27;
UINT64 v28;
unsigned int i;
UINT64 v30;
unsigned int v31;
unsigned int v32;
__int64 v33;
unsigned __int16 v34;
unsigned __int64 v35;
__int64 v36;
unsigned __int16 v37;
__int64 v38;
unsigned int v39;
unsigned int v40;
unsigned int v41;
unsigned __int64 v42;
__int64 v43;
unsigned int v44;
unsigned __int64 v45;
unsigned __int64 v46;
unsigned int v47;
unsigned int v48;
unsigned __int64 v49;
unsigned __int64 v50;
__int64 v51;
BOOL v52;
__int64 v53;
__int64 v55;
int v56;
UINT64 v57;
unsigned __int64 v58;
unsigned __int64 v59;
UINT64 v60;
UINT8 CurrentIrql;
UINT8 v62;
int v63;
unsigned __int64 v64;
__int64 v65;
unsigned int v66;
UINT64 v67;
unsigned __int64 v68;
unsigned __int64 v69;
unsigned int SessionId;
_ETHREAD *v71;
int v72;
int v73;
__int64 v74;
int v75;
_KLOCK_ENTRY *v76;
__int64 v77;
_ETHREAD *CurrentThread;
INT64 v79;
int v80;
int v81;
__int64 Thread;
_ETHREAD *Threada;
unsigned __int64 v84;
_KLOCK_ENTRY *v85;
UINT8 v86;
__int64 v87;
unsigned int v88;
UINT64 a3a;
int v90;
unsigned int v91;
v7 = a4;
v8 = *(_QWORD *)&SpinLock;
v9 = WORD1(RtlpHpHeapGlobals) ^ WORD1(a3) ^ *(unsigned __int16 *)(a3 + 2);
RtlRbRemoveNode((UINT64 *)(*(_QWORD *)&SpinLock + 16i64), a3 + 8);
v11 = 0i64;
v12 = a3 - a2;
v13 = (a3 - a2 + 4127) & 0xFFFFF000;
v14 = ((a3 + 16 * (((unsigned int)a3 ^ (unsigned int)RtlpHpHeapGlobals ^ *(_DWORD *)a3) >> 16) - a2) & 0xFFFFF000)
- v13;
if( v13 >= (((_DWORD)a3
+ 16 * (((unsigned int)a3 ^ (unsigned int)RtlpHpHeapGlobals ^ *(_DWORD *)a3) >> 16)
- (_DWORD)a2) & 0xFFFFF000) )
v14 = 0;
*(_QWORD *)(v8 + 56) -= (v14 >> 12)
+ (unsigned int)((16
* (((unsigned int)a3 ^ (unsigned int)RtlpHpHeapGlobals ^ *(_DWORD *)a3) >> 16)
+ (unsigned __int64)(a3 & 0xFFF)
+ 4095) >> 12)
- (unsigned int)(((unsigned __int64)(16
* (((unsigned int)a3 ^ (unsigned int)RtlpHpHeapGlobals ^ *(_DWORD *)a3) >> 16))
+ 4095) >> 12)
- (unsigned __int16)(a3 ^ RtlpHpHeapGlobals ^ *(_WORD *)a3);
v15 = v9 - v7;
if( v15 && (*(_DWORD *)(v8 + 176) & 1) != 0 )
{
v16 = (((a3 + 16i64 * v7 + 4095) & 0xFFFFFFFFFFFFF000ui64) - (a3 + 16i64 * v7)) >> 4;
v17 = 16 * v16;
if( (unsigned int)(16 * v16) < 0x20 )
{
v7 += v16;
v15 -= v16;
}
else if( (v17 & 0xFFFFFFC0) == 0 && v17 != 32 )
{
++v7;
--v15;
}
}
if( (unsigned int)(16 * v15) < 0x20 )
v7 += v15;
v18 = 0;
if( (unsigned int)(16 * v15) >= 0x20 )
v18 = v15;
v90 = v18;
v19 = 16 * v7 + 32;
*(_BYTE *)(a3 + 6) = BYTE6(a3) ^ BYTE6(RtlpHpHeapGlobals) ^ 1;
v20 = (unsigned __int8)(RtlpHpHeapGlobals ^ (v12 >> 12) ^ a3);
v21 = v90;
v22 = v90 == 0;
*(_DWORD *)(a3 + 8) = v20;
v23 = v21;
if( v22 )
v19 = 16 * v7;
v24 = (0xFFFFFFFFFFFFFFFFui64 >> (63 - (unsigned __int8)((v12 - 1 + v19) >> 12))) & (-1i64 << (v12 >> 12));
v25 = (v24 ^ *(_QWORD *)(a2 + 16)) & v24;
if( v25 )
{
v22 = (a5 & 1) == 0;
v56 = a5 & 1;
*(_DWORD *)(a3 + 8) = v20 | 0x200;
v81 = v56;
if( v22 )
RtlpHpReleaseQueuedLockExclusive(*(unsigned int *)(v8 + 8), a6);
v57 = a2 + 24;
_BitScanForward64(&v58, v25);
v84 = (0x101010101010101i64
* ((((v25 - ((v25 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v25 - ((v25 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((v25 - ((v25 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v25 - ((v25 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56;
_BitScanReverse64(&v59, v25);
v60 = a2 + (unsigned int)((_DWORD)v58 << 12);
v80 = v59 - v58 + 1;
v91 = v80 << 12;
Thread = ((1i64 << v80) - 1) << v58;
if( *(_DWORD *)(v8 + 8) )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
ExpAcquireSpinLockExclusive((INT64 *)(a2 + 24), CurrentIrql);
v62 = CurrentIrql;
v57 = a2 + 24;
v86 = v62;
}
else
{
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v86 = 0;
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(a2 + 24), 0i64);
}
v63 = ((__int64(__fastcall *)(INT64, UINT64, _QWORD))(v8 ^ RtlpHpHeapGlobals ^ *(_QWORD *)(v8 + 152)))(
v8 ^ *(_QWORD *)(v8 + 128),
v60,
v91);
if( v63 >= 0 )
{
*(_QWORD *)(a2 + 16) |= Thread;
_InterlockedExchangeAdd64((volatile signed __int64 *)(v8 + 48), v84);
v63 = 0;
}
if( *(_DWORD *)(v8 + 8) )
{
*(_DWORD *)v57 = 0;
__writecr8(v86);
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v57, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)v57);
LODWORD(a3a) = 0;
Threada = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType(v57) == 1 )
SessionId = MmGetSessionIdEx(Threada->Tcb.ApcState.Process);
else
SessionId = -1;
v71 = Threada;
--Threada->Tcb.SpecialApcDisable;
++Threada->Tcb.AbAllocationRegionCount;
v72 = (char)v71->Tcb.AbEntrySummary | (char)v71->Tcb.AbOrphanedEntrySummary;
LOBYTE(v91) = Threada->Tcb.AbAllocationRegionCount;
v73 = v72 ^ 0x3F;
v22 = !_BitScanReverse((unsigned int *)&v74, v73);
if( v22 )
goto LABEL_116;
while( 1 )
{
v75 = ~(1 << v74);
v76 = &Threada->Tcb.LockEntries[v74];
v73 &= v75;
v85 = v76;
if( (v76->AcquiredByte & 1) != 0
&& (v76->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v76->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v57 & 0x7FFFFFFFFFFFFFFCi64)
&& v76->LockState.SessionId == SessionId )
{
v76->AcquiredByte &= ~1u;
if( v76->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
break;
}
v22 = !_BitScanReverse((unsigned int *)&v74, v73);
if( v22 )
goto LABEL_116;
}
if( !v76 )
{
LABEL_116:
if( (*(&Threada->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, Threada, (PVOID)v57, (PVOID)SessionId, 0i64);
}
else
{
v76->CrossThreadReleasableAndBusyByte |= 2u;
if( v76->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
{
KiAbEntryRemoveFromTree(v76);
v76 = v85;
v71 = Threada;
}
LODWORD(a3a) = v76->BoostBitmap.AllFields & 0x1FFFF;
v76->BoostBitmap.AllFields &= 0xFFFE0000;
v76->ThreadLocalFlags &= ~1u;
v76->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v77 = v76 - v71->Tcb.LockEntries;
if( (_BYTE)v91 == 1 )
v71->Tcb.AbEntrySummary |= 1 << v77;
else
_InterlockedOr8((volatile signed __int8 *)&v71->Tcb.AbOrphanedEntrySummary, 1 << v77);
}
--v71->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v71->Tcb, (VOID *)v57, &a3a);
v22 = Threada->Tcb.SpecialApcDisable++ == -1;
if( v22 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)Threada->Tcb.ApcState.ApcListHead[0].Flink != &Threada->Tcb.152 )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
}
v23 = v90;
if( v63 < 0 )
{
v23 = v90 + v7;
v7 = 0;
}
if( !v81 )
RtlpHpAcquireQueuedLockExclusive(v8, (UINT64 *)*(unsigned int *)(v8 + 8));
*(_DWORD *)(a3 + 8) &= ~0x200u;
}
*(_WORD *)(a3 + 2) = WORD1(RtlpHpHeapGlobals) ^ v7 ^ WORD1(a3);
if( v23 )
{
v26 = 16i64 * v7 + a3;
if( v7 )
v27 = (unsigned __int16)v7;
else
v27 = (unsigned __int16)(WORD2(RtlpHpHeapGlobals) ^ WORD2(v26) ^ HIDWORD(*(_QWORD *)v26));
HIDWORD(v87) = v27 & 0xFF00FFFF | 0x10000;
LODWORD(v87) = v23 << 16;
*(_QWORD *)v26 = v87 ^ RtlpHpHeapGlobals ^ v26;
v28 = v26 + 16i64 * v23;
*(_DWORD *)(v26 + 8) = (unsigned __int8)(RtlpHpHeapGlobals ^ v26 ^ ((unsigned int)(v26 - a2) >> 12));
if( v28 < a2 + 16 * (*(unsigned __int16 *)(a2 + 32) + 3i64) )
*(_WORD *)(v28 + 4) = WORD2(v28) ^ WORD2(RtlpHpHeapGlobals) ^ v23;
for( i = 0; ; i = v31 )
{
v30 = a2 + 48;
v91 = i;
v31 = ((unsigned int)RtlpHpHeapGlobals ^ (unsigned int)v26 ^ *(_DWORD *)v26) >> 16;
v88 = v31;
v32 = (unsigned __int16)(((unsigned __int64)RtlpHpHeapGlobals ^ v26 ^ *(_QWORD *)v26) >> 32);
*(_BYTE *)(v26 + 6) = BYTE6(RtlpHpHeapGlobals) ^ BYTE6(v26);
if( v32 )
{
a3a = v26 - 16i64 * v32;
v33 = RtlpHpHeapGlobals ^ *(_QWORD *)a3a ^ a3a;
if( (v33 & 0xFF000000000000i64) == 0 )
{
RtlpHpVsFreeChunkRemove(v8, a2, v26 - 16i64 * v32);
v26 = a3a;
v30 = a2 + 48;
i = v91;
v31 += WORD1(v33);
}
}
v34 = *(_WORD *)(a2 + 32);
v35 = v26 + 16i64 * v31;
if( v35 < v30 + 16i64 * v34 )
{
v36 = RtlpHpHeapGlobals ^ v35 ^ *(_QWORD *)v35;
if( (v36 & 0xFF000000000000i64) == 0 )
{
RtlpHpVsFreeChunkRemove(v8, a2, v35);
v34 = *(_WORD *)(a2 + 32);
v30 = a2 + 48;
i = v91;
v31 += WORD1(v36);
}
}
v37 = v34;
if( (*(_DWORD *)(v8 + 176) & 1) != 0 )
{
v35 = v26 + 16i64 * v31;
if( v35 < v30 + 16i64 * v34 )
{
v38 = RtlpHpHeapGlobals ^ v35 ^ *(_QWORD *)v35;
if( (v38 & 0xFF000000000000i64) == 0 )
{
RtlpHpVsFreeChunkRemove(v8, a2, v35);
v37 = *(_WORD *)(a2 + 32);
v30 = a2 + 48;
i = v91;
v31 += WORD1(v38);
}
}
}
if( v88 != v31 )
{
v35 = v26 + 16i64 * v31;
*(_WORD *)(v26 + 2) = WORD1(RtlpHpHeapGlobals) ^ v31 ^ WORD1(v26);
v37 = *(_WORD *)(a2 + 32);
if( v35 < v30 + 16i64 * v37 )
{
*(_WORD *)(v35 + 4) = WORD2(RtlpHpHeapGlobals) ^ WORD2(v35) ^ v31;
v37 = *(_WORD *)(a2 + 32);
}
}
if( v31 == v37 )
{
RtlpHpVsSubsegmentCleanup(v8, a2, v35, v30);
return v7;
}
if( v31 <= i )
break;
v39 = (v26 - a2 + 4127) & 0xFFFFF000;
v40 = (v26 + 16 * (WORD1(RtlpHpHeapGlobals) ^ WORD1(v26) ^ *(unsigned __int16 *)(v26 + 2)) - a2) & 0xFFFFF000;
if( v39 < v40 )
{
v41 = v40 - v39;
v42 = *(_QWORD *)(a2 + 16) & (-1i64 << (v39 >> 12)) & (0xFFFFFFFFFFFFFFFFui64 >> (63
- (unsigned __int8)((unsigned __int64)(v40 - 1) >> 12)));
}
else
{
v41 = 0;
v42 = 0i64;
}
if( v41 < 0x1000 )
break;
if( !v42 )
break;
v68 = (0x101010101010101i64
* ((((v42 - ((v42 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v42 - ((v42 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((v42 - ((v42 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v42 - ((v42 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56;
a3a = v68;
if( *(__int16 *)(a2 + 34) < 0 )
break;
if( (*(_DWORD *)(v8 + 176) & 2) == 0 )
{
v69 = *(_QWORD *)(v8 + 48) >> 7;
if( v69 <= 8 )
v69 = 8i64;
if( *(_QWORD *)(v8 + 56) + (unsigned __int64)(unsigned int)v68 <= v69 )
break;
}
*(_BYTE *)(v26 + 6) = BYTE6(RtlpHpHeapGlobals) ^ BYTE6(v26) ^ 1;
*(_DWORD *)(v26 + 8) = (unsigned __int8)(RtlpHpHeapGlobals ^ v26 ^ ((unsigned int)(v26 - a2) >> 12)) | 0x200;
v91 = a5 & 1;
if( (a5 & 1) == 0 )
{
RtlpHpReleaseQueuedLockExclusive(*(unsigned int *)(v8 + 8), a6);
LODWORD(v68) = a3a;
}
LODWORD(v79) = 0;
RtlpHpVsSubsegmentCommitPages(v8, a2, v42, (unsigned int)v68, v79);
if( !v91 )
RtlpHpAcquireQueuedLockExclusive(v8, (UINT64 *)*(unsigned int *)(v8 + 8));
*(_DWORD *)(v26 + 8) &= ~0x200u;
}
if( (*(_DWORD *)(v8 + 176) & 1) != 0
&& ((v26 + 32) & 0xFFF) != 0
&& ((v26 + 4111) & 0xFFFFFFFFFFFFF000ui64) - v26 < 16
* (unsigned __int64)(WORD1(RtlpHpHeapGlobals) ^ WORD1(v26) ^ *(unsigned __int16 *)(v26 + 2)) )
{
v64 = ((v26 + 4111) & 0xFFFFFFFFFFFFF000ui64) - 32;
v65 = (__int64)(v64 - v26) >> 4;
v66 = (WORD1(RtlpHpHeapGlobals) ^ WORD1(v26) ^ *(unsigned __int16 *)(v26 + 2)) - v65;
*(_WORD *)(v26 + 2) = WORD1(RtlpHpHeapGlobals) ^ v65 ^ WORD1(v26);
*(_OWORD *)v64 = 0i64;
*(_OWORD *)(v64 + 16) = 0i64;
*(_WORD *)(v64 + 2) = v66;
v67 = v64 + 16i64 * v66;
*(_WORD *)(v64 + 4) = v65;
*(_QWORD *)v64 ^= RtlpHpHeapGlobals ^ v64;
if( v67 < a2 + 16 * (*(unsigned __int16 *)(a2 + 32) + 3i64) )
*(_WORD *)(v67 + 4) = WORD2(RtlpHpHeapGlobals) ^ WORD2(v67) ^ v66;
RtlpHpVsFreeChunkInsert((UINT64 *)v8, a2, (_WORD *)v64);
}
v43 = 16 * (WORD1(RtlpHpHeapGlobals) ^ WORD1(v26) ^ *(unsigned __int16 *)(v26 + 2));
v44 = (v26 - a2 + 4127) & 0xFFFFF000;
v45 = ((unsigned __int64)(v26 & 0xFFF) + v43 + 4095) >> 12;
v46 = (unsigned __int64)(v43 + 4095) >> 12;
v47 = (v43 + v26 - a2) & 0xFFFFF000;
if( v44 < v47 )
{
v48 = v47 - v44;
v49 = *(_QWORD *)(a2 + 16) & (-1i64 << (v44 >> 12)) & (0xFFFFFFFFFFFFFFFFui64 >> (63
- (unsigned __int8)((unsigned __int64)(v47 - 1) >> 12)));
}
else
{
v48 = 0;
v49 = 0i64;
}
v50 = v49 - ((v49 >> 1) & 0x5555555555555555i64);
*(_QWORD *)(v8 + 56) += (unsigned int)((0x101010101010101i64
* (((v50 & 0x3333333333333333i64)
+ ((v50 >> 2) & 0x3333333333333333i64)
+ (((v50 & 0x3333333333333333i64) + ((v50 >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24;
*(_WORD *)v26 = RtlpHpHeapGlobals ^ v26 ^ (v45
+ (v48 >> 12)
- v46
- ((0x101010101010101i64
* (((v50 & 0x3333333333333333i64)
+ ((v50 >> 2) & 0x3333333333333333i64)
+ (((v50 & 0x3333333333333333i64) + ((v50 >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56));
v51 = *(_QWORD *)(v8 + 24);
if( (v51 & 1) != 0 )
{
v55 = *(_QWORD *)(v8 + 16);
if( v55 )
v11 = v55 ^ (v8 + 16);
}
else
{
v11 = *(_QWORD *)(v8 + 16);
}
v52 = 0;
if( v11 )
{
while( 1 )
{
if( ((unsigned int)RtlpHpHeapGlobals ^ *(_DWORD *)v26 ^ (unsigned int)v26) < ((unsigned int)RtlpHpHeapGlobals ^ ((_DWORD)v11 - 8) ^ *(_DWORD *)(v11 - 8)) )
{
v53 = *(_QWORD *)v11;
if( (v51 & 1) != 0 )
{
if( !v53 )
goto LABEL_57;
v53 ^= v11;
}
if( !v53 )
{
LABEL_57:
v52 = 0;
break;
}
}
else
{
v53 = *(_QWORD *)(v11 + 8);
if( (v51 & 1) != 0 )
{
if( !v53 )
goto LABEL_50;
v53 ^= v11;
}
if( !v53 )
{
LABEL_50:
v52 = 1;
break;
}
}
v11 = v53;
}
}
RtlRbInsertNodeEx((UINT64 *)(v8 + 16), v11, v52, v26 + 8);
}
return v7;
}Referenced by:
RtlpHpVsContextAllocateInternal