KiExpandKernelStackAndCalloutOnStackSegment

__int64 __fastcall KiExpandKernelStackAndCalloutOnStackSegment(
        VOID (*a1)(void),
        void *a2,
        unsigned __int64 a3,
        char a4,
        __int64 a5){
  char v5; 
  unsigned __int64 v6; 
  _ETHREAD *CurrentThread; 
  unsigned __int8 v8; 
  unsigned int v9; 
  unsigned __int8 CurrentIrql; 
  __int64 v11; 
  unsigned int v12; 
  int v13; 
  int v14; 
  _QWORD *KernelStack; 
  _KPROFILE_SOURCE v16; 
  UINT64 v17; 
  _QWORD *v18; 
  INT64 v19; 
  __int64 v20; 
  __int32 bf_0; 
  int v22; 
  UINT64 v23; 
  unsigned int v24; 
  unsigned int v25; 
  __int64 v27; 
  __int64 v28; 
  __int64 v29; 
  bool v30; 
  unsigned __int8 v31; 
  PLARGE_INTEGER v32; 
  __int64 v33; 
  UINT64 v34; 
  struct _KPRCB *v35; 
  int v38; 
  UINT64 DeleteFlags; 

  v5 = a4;
  v33 = 0i64;
  v6 = a3;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v8 = 0;
  v9 = 0;
  v32 = 0i64;
  CurrentIrql = KeGetCurrentIrql();
  v11 = a5;
  if( CurrentIrql == 2 )
  {
    v32 = (PLARGE_INTEGER)&v33;
    if( a5 )
      v8 = 16;
  }
  if( (a4 & 8) != 0 && a5 )
    v8 = 16;
  v12 = 0;
  if( a3 > (unsigned int)KeKernelStackSize )
  {
    v8 |= 1u;
    v12 = 1;
    v9 = 1;
    if( a5 && *(_BYTE *)(a5 + 4) )
      v12 = 5;
  }
  else
  {
    v5 = a4 | 4;
    v6 = 0i64;
  }
  LODWORD(DeleteFlags) = v9;
  if( (v8 & 0xF0) == 0 )
  {
    v13 = v12 | 2;
    if( (v5 & 2) != 0 )
      v13 = v12;
    v12 = v13 | 0x10;
    v14 = v5 & 4;
    if( !v14 )
      v12 = v13;
    KernelStack = MmCreateKernelStack(
                    v12,
                    LOBYTE((*(&KiProcessorBlock + CurrentThread->Tcb.IdealProcessor))->ParentNode->NodeNumber),
                    &CurrentThread->Tcb);
    v9 |= 4u;
    v18 = KernelStack;
    if( !v14 )
      v9 = DeleteFlags;
    if( KernelStack )
      goto LABEL_13;
    v11 = a5;
  }
  if( !v11 || (v8 & 1) != 0 && !*(_BYTE *)(v11 + 4) )
    return 3221225495i64;
  if( _bittestandset((signed __int32 *)&CurrentThread->Tcb.116, 0xFu) )
    v8 |= 4u;
  if( KeWaitForSingleObject(v11 + 8, 25, 0, 0, (INT64)v32) == 258 )
  {
    CurrentThread->Tcb._bf_0 ^= (CurrentThread->Tcb._bf_0 ^ (v8 << 13)) & 0x8000;
    return 3221227272i64;
  }
  v27 = *(unsigned __int8 *)(v11 + 6);
  if( (unsigned __int8)v27 >= *(_BYTE *)(v11 + 5) )
  {
    KeReleaseMutant((_KMUTANT *)(v11 + 8), 1i64, 0, 0);
    return 3221225495i64;
  }
  v18 = *(_QWORD **)(v11 + 8 * v27 + 64);
  v8 |= 8u;
  v28 = a5;
  *(_BYTE *)(a5 + 6) = v27 + 1;
  if( (v8 & 1) == 0 && *(_BYTE *)(v28 + 4) )
  {
    LOBYTE(v12) = 5;
    v6 = 71680i64;
    v8 |= 1u;
  }
LABEL_13:
  *(v18 - 6) = v18;
  v19 = (INT64)(v18 - 6);
  if( (v8 & 1) != 0 )
  {
    v20 = (__int64)v18 - 73727;
  }
  else
  {
    v17 = (unsigned int)KeKernelStackSize;
    v20 = (__int64)v18 - (unsigned int)KeKernelStackSize + 1;
  }
  *(_QWORD *)(v19 + 8) = v20;
  *(_QWORD *)(v19 + 16) = CurrentThread->Tcb.StackBase;
  *(_QWORD *)(v19 + 40) = CurrentThread->Tcb.InitialStack;
  if( (v12 & 1) != 0 )
  {
    v19 |= 1ui64;
    if( (v12 & 4) != 0 )
      v19 |= 2ui64;
  }
  bf_0 = CurrentThread->Tcb._bf_0;
  if( (bf_0 & 0x1000) != 0 )
  {
    v8 |= 2u;
    LOBYTE(DeleteFlags) = 2;
  }
  else
  {
    LOBYTE(DeleteFlags) = 0;
    CurrentThread->Tcb._bf_0 = bf_0 | 0x1000;
  }
  v22 = 0;
  v35 = 0i64;
  v34 = 0i64;
  v38 = 0;
  LODWORD(v23) = KeGetCurrentStackPointer(v17, v16);
  KeQueryCurrentStackInformationEx(v23, (char *)&v38, &v35, &v34);
  if( v38 == 10 )
  {
    v22 = 1;
    __writegsbyte(0x80A6u, 1u);
  }
  KiSwitchKernelStackAndCallout((INT64)a2, a1, v19, v6);
  v25 = v24;
  if( v22 )
    __writegsbyte(0x80A6u, 0);
  if( (v8 & 8) != 0 )
  {
    v29 = a5;
    v30 = (*(_BYTE *)(a5 + 6))-- == 1;
    if( v30 && (v8 & 4) == 0 )
      CurrentThread->Tcb._bf_0 &= ~0x8000u;
    KeReleaseMutant((_KMUTANT *)(v29 + 8), 1i64, 0, 0);
  }
  else
  {
    MmDeleteKernelStack(v18, v9);
  }
  if( !(_BYTE)DeleteFlags )
    CurrentThread->Tcb._bf_0 &= ~0x1000u;
  if( KeGetCurrentIrql() != CurrentIrql )
  {
    v31 = KeGetCurrentIrql();
    KeBugCheckEx(0xC8u, (PVOID)(((CurrentIrql | ((unsigned __int64)v31 << 8)) << 8) | 2), a1, a2, 0i64);
  }
  return v25;
}

Referenced by:

KiExpandKernelStackAndCalloutSwitchStack