KiExpandKernelStackAndCalloutOnStackSegment

__int64 __fastcall KiExpandKernelStackAndCalloutOnStackSegment(
        void (*a1)(void),
        ULONG_PTR a2,
        unsigned __int64 a3,
        char a4,
        __int64 a5){
  char v5; 
  __int64 v6; 
  _ETHREAD *CurrentThread; 
  unsigned __int8 v8; 
  unsigned int v9; 
  unsigned __int8 CurrentIrql; 
  __int64 v11; 
  int v12; 
  int v13; 
  int v14; 
  __int64 KernelStack; 
  KPROFILE_SOURCE v16; 
  UINT64 v17; 
  _QWORD *v18; 
  __int64 v19; 
  __int64 v20; 
  int v21; 
  int v22; 
  UINT64 v23; 
  unsigned int v24; 
  unsigned int v25; 
  __int64 v27; 
  __int64 v28; 
  __int64 v29; 
  bool v30; 
  unsigned __int8 v31; 
  int Timeout; 
  int v33; 
  union _LARGE_INTEGER *v34; 
  __int64 v35; 
  UINT64 a4a; 
  void *a3a[10]; 
  int a2a; 
  UINT64 DeleteFlags; 
  v5 = a4;
  v35 = 0i64;
  v6 = a3;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v8 = 0;
  v9 = 0;
  v34 = 0i64;
  CurrentIrql = KeGetCurrentIrql();
  v11 = a5;
  if( CurrentIrql == 2 )
  {
    v34 = (union _LARGE_INTEGER *)&v35;
    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,
                    *(unsigned __int8 *)(*((_QWORD *)*(&KiProcessorBlock + *((unsigned int *)CurrentThread + 147)) + 24)
                                       + 146i64),
                    (unsigned __int64)CurrentThread);
    v9 |= 4u;
    v18 = (_QWORD *)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 + 29, 0xFu) )
    v8 |= 4u;
  if( KeWaitForSingleObject((PVOID)(v11 + 8), WrCalloutStack, 0, 0, v34) == 258 )
  {
    *((_DWORD *)CurrentThread + 29) ^= (*((_DWORD *)CurrentThread + 29) ^ (v8 << 13)) & 0x8000;
    return 3221227272i64;
  }
  v27 = *(unsigned __int8 *)(v11 + 6);
  if( (unsigned __int8)v27 >= *(_BYTE *)(v11 + 5) )
  {
    KeReleaseMutant((PRKMUTANT)(v11 + 8), 1, 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) = *((_QWORD *)CurrentThread + 7);
  *(_QWORD *)(v19 + 40) = *((_QWORD *)CurrentThread + 5);
  if( (v12 & 1) != 0 )
  {
    v19 |= 1ui64;
    if( (v12 & 4) != 0 )
      v19 |= 2ui64;
  }
  v21 = *((_DWORD *)CurrentThread + 29);
  if( (v21 & 0x1000) != 0 )
  {
    v8 |= 2u;
    LOBYTE(DeleteFlags) = 2;
  }
  else
  {
    LOBYTE(DeleteFlags) = 0;
    *((_DWORD *)CurrentThread + 29) = v21 | 0x1000;
  }
  v22 = 0;
  a3a[0] = 0i64;
  a4a = 0i64;
  a2a = 0;
  LODWORD(v23) = KeGetCurrentStackPointer(v17, v16);
  KeQueryCurrentStackInformationEx(v23, &a2a, (CHAR **)a3a, &a4a);
  if( a2a == 10 )
  {
    v22 = 1;
    __writegsbyte(0x80A6u, 1u);
  }
  KiSwitchKernelStackAndCallout(a2, a1, v19, v6, Timeout, v33, (__int64)v34);
  v25 = v24;
  if( v22 )
    __writegsbyte(0x80A6u, 0);
  if( (v8 & 8) != 0 )
  {
    v29 = a5;
    v30 = (*(_BYTE *)(a5 + 6))-- == 1;
    if( v30 && (v8 & 4) == 0 )
      *((_DWORD *)CurrentThread + 29) &= ~0x8000u;
    KeReleaseMutant((PRKMUTANT)(v29 + 8), 1, 0, 0);
  }
  else
  {
    MmDeleteKernelStack(v18, v9);
  }
  if( !(_BYTE)DeleteFlags )
    *((_DWORD *)CurrentThread + 29) &= ~0x1000u;
  if( KeGetCurrentIrql() != CurrentIrql )
  {
    v31 = KeGetCurrentIrql();
    KeBugCheckEx(0xC8u, ((CurrentIrql | ((unsigned __int64)v31 << 8)) << 8) | 2, (ULONG_PTR)a1, a2, 0i64);
  }
  return v25;
}

Referenced by:

KiExpandKernelStackAndCalloutSwitchStack