KiExpandKernelStackAndCalloutSwitchStack

__int64 __fastcall KiExpandKernelStackAndCalloutSwitchStack(
        VOID (*a1)(void),
        void *a2,
        unsigned __int64 a3,
        char a4,
        __int64 a5){
  _ETHREAD *CurrentThread; 
  _BYTE *v10; 
  _KPROFILE_SOURCE v11; 
  INT64 v12; 
  VOID *v13; 
  struct _KPRCB *StackLimit; 
  _BYTE *v15; 
  struct _KPRCB *v16; 
  UINT64 CurrentIrql; 
  UINT64 v19; 
  struct _KPRCB *v20; 
  __int64 v21[6]; 
  int v22; 

  v20 = 0i64;
  v21[0] = 0i64;
  v22 = 0;
  if( a3 > 0x11800 )
    return 3221225713i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  LODWORD(v10) = KeGetCurrentStackPointer((UINT64)a1, (_KPROFILE_SOURCE)a2);
  StackLimit = (struct _KPRCB *)CurrentThread->Tcb.StackLimit;
  v15 = v10;
  v16 = (struct _KPRCB *)(*((_QWORD *)CurrentThread->Tcb.InitialStack + 1) & 0xFFFFFFFFFFFFFFFEui64);
  CurrentIrql = KeGetCurrentIrql();
  if( (_BYTE)CurrentIrql == 2 )
  {
    if( (a4 & 2) != 0 )
      return 3221225714i64;
    LODWORD(v19) = KeGetCurrentStackPointer(CurrentIrql, v11);
    if( !KeQueryCurrentStackInformationEx(v19, (char *)&v22, &v20, (UINT64 *)v21) )
      __fastfail(4u);
    if( v22 == 1 || v22 == 10 )
    {
      StackLimit = v20;
      v16 = v20;
    }
  }
  else
  {
    if( (unsigned __int8)CurrentIrql > 2u )
      KeBugCheckEx(0xAu, (PVOID)2, (PVOID)(unsigned __int8)CurrentIrql, 0i64, 0i64);
    if( a3 == (unsigned int)KeKernelStackSize || a3 == 24576 && (unsigned int)KeKernelStackSize >= 0x6000 )
      a4 |= 5u;
  }
  if( v15 - (_BYTE *)v16 < a3
    || (a4 & 1) != 0
    || v15 - (_BYTE *)StackLimit < a3 && MmGrowKernelStackEx(v15, a3, v12, v13) < 0 )
  {
    return KiExpandKernelStackAndCalloutOnStackSegment(a1, a2, a3, a4, a5);
  }
  else
  {
    return 3221226635i64;
  }
}

Referenced by:

KeExpandKernelStackAndCalloutInternal