MmGrowKernelStackEx
NTSTATUS __stdcall MmGrowKernelStackEx(VOID *CurrentStack, UINT64 CommitSize, INT64 a3, VOID *a4){
_ETHREAD *CurrentThread;
NTSTATUS v6;
_MI_PARTITION *v7;
unsigned __int8 CurrentIrql;
_MMPTE *PteBase;
char *v10;
UINT64 v11;
_ETHREAD *v12;
struct _KPRCB *CurrentPrcb;
__int64 CachedResidentAvailable;
bool v16;
signed __int32 v17;
UINT64 StackFlags;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( (char *)CurrentThread->Tcb.StackBase
- (*((_QWORD *)CurrentThread->Tcb.InitialStack + 1) & 0xFFFFFFFFFFFFFFFEui64) < (void *)0x12000 )
return -1073741637;
v6 = 0;
v7 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8i64 * CurrentThread->Tcb.Process->Vm.Instance.PartitionId);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
PteBase = MmGetPteBase();
v10 = (char *)PteBase + (((unsigned __int64)CurrentThread->Tcb.StackLimit >> 9) & 0x7FFFFFFFF8i64);
v11 = (UINT64)PteBase + ((((unsigned __int64)CurrentStack - CommitSize) >> 9) & 0x7FFFFFFFF8i64);
if( v11 < (unsigned __int64)v10 )
{
if( v11 < (unsigned __int64)PteBase + ((*((_QWORD *)CurrentThread->Tcb.InitialStack + 1) >> 9) & 0x7FFFFFFFF8i64) )
{
++*(&stru_140C4DB30 + 882);
v6 = -1073741571;
}
else
{
v12 = (_ETHREAD *)(((__int64)&v10[-v11 - 8] >> 3) + 1);
if( MiChargeResident((ULONG_PTR *)&v7->Core.PartitionId, (UINT64)v12, 0i64) )
{
LODWORD(StackFlags) = MI_GET_NODE_FROM_VALID_PTE(
(INT64)&MmGetPteBase()[-1]
+ (((unsigned __int64)CurrentThread->Tcb.StackBase >> 9) & 0x7FFFFFFFF8i64));
if( MiAllocateKernelStackPages((PVOID *)v7, v11, &v12->Tcb, (unsigned __int16)CurrentThread | 1, StackFlags) )
{
CurrentThread->Tcb.StackLimit = (void *volatile)((__int64)((v11 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16);
}
else
{
if( v7 == &Irp )
{
CurrentPrcb = KeGetCurrentPrcb();
CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable;
if( (_DWORD)CachedResidentAvailable != -1 )
{
if( (unsigned __int64)v12 + CachedResidentAvailable <= 0x100 )
{
do
{
if( (unsigned __int64)v12 >= 0x80000 )
break;
v17 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
CachedResidentAvailable + (_DWORD)v12,
CachedResidentAvailable);
v16 = (_DWORD)CachedResidentAvailable == v17;
LODWORD(CachedResidentAvailable) = v17;
if( v16 )
goto LABEL_24;
}
while( v17 != -1 && (unsigned __int64)v12 + v17 <= 0x100 );
}
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
v12 = (_ETHREAD *)((char *)v12 + (int)CachedResidentAvailable - 192);
}
}
}
if( v12 )
_InterlockedExchangeAdd64((volatile signed __int64 *)&v7->Vp.ResidentAvailablePages, (unsigned __int64)v12);
LABEL_24:
v6 = -1073741670;
}
}
else
{
v6 = -1073741801;
}
}
}
__writecr8(CurrentIrql);
return v6;
}Referenced by:
KiExpandKernelStackAndCalloutSwitchStack
KxSwitchKernelStackCallout
MmGrowKernelStack