MiUnlinkNodeLargePages

INT64 __fastcall MiUnlinkNodeLargePages(
        INT64 a1,
        UINT64 a2,
        INT64 a3,
        UINT64 a4,
        INT64 a5,
        INT64 a6,
        INT64 a7,
        INT64 a8,
        UINT64 a9){
  __int64 v9; 
  char v10; 
  UINT8 v11; 
  _MI_NODE_INFORMATION *v12; 
  char *v13; 
  __int64 v14; 
  unsigned __int8 CurrentIrql; 
  unsigned int v16; 
  __int64 v17; 
  int v18; 
  unsigned int v19; 
  __int64 *v20; 
  __int64 v21; 
  char *v22; 
  char *v23; 
  unsigned int v24; 
  __int64 v25; 
  unsigned int v26; 
  __int64 v27; 
  __int64 *v28; 
  __int64 v29; 
  unsigned int v30; 
  __int64 v31; 
  __int64 v32; 
  __int64 v33; 
  __int64 v34; 
  unsigned int v35; 
  unsigned int v36; 
  unsigned int v37; 
  __int64 v38; 
  __int64 v39; 
  int v40; 
  INT64 *v41; 
  __int64 v42; 
  BOOL v43; 
  unsigned int v44; 
  int v45; 
  INT64 v46; 
  _MMPFN *v47; 
  volatile signed __int64 *v48; 
  signed __int8 v49; 
  BOOL v50; 
  INT64 **v51; 
  _QWORD *v52; 
  RTL_BALANCED_NODE *v53; 
  bool v54; 
  char v55; 
  _MMPFN *v56; 
  _MMPFN *v57; 
  _MMPFN *v58; 
  INT64 v59; 
  _MMPFN *v60; 
  _MMPFN *v61; 
  BOOL v63; 
  unsigned int v64; 
  unsigned int Channel; 
  char *v66; 
  __int64 v67; 
  UINT64 SpinCount; 
  __int64 v69; 
  __int64 v70; 
  _MMPFN *Pfn1; 
  __int64 v72; 
  __int64 v73; 
  _MI_NODE_INFORMATION *NodeInformation; 
  UINT64 v75; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  __int64 v77; 
  int PcValue[2]; 
  __int64 v79[2]; 
  __int64 v80; 
  __int64 v81; 
  INT64 v82; 
  unsigned int LargePageIndex; 
  char v86; 
  char v87; 
  LargePageIndex = a2;
  v9 = *(_QWORD *)(a1 + 16);
  v10 = a8;
  memset(&LockHandle, 0, sizeof(LockHandle));
  v11 = a2;
  v12 = (_MI_NODE_INFORMATION *)(4544i64 * (unsigned int)a4 + v9);
  v86 = 0;
  v80 = 4544i64 * (unsigned int)a4;
  NodeInformation = v12;
  if( !*((_QWORD *)v12 + 522) && (MiFlags & 0x30) != 0 )
    return 0i64;
  v13 = (char *)v12 + 1072 * (unsigned int)a2;
  v82 = MiLargePageSizes[(unsigned int)a2];
  HIDWORD(SpinCount) = dword_140C4DCC0[(unsigned int)a2];
  v66 = v13;
  if( (a8 & 4) != 0 )
    v69 = 0x100000000i64;
  else
    v69 = 1i64;
  v14 = (a8 & 1) == 0;
  v70 = v14;
  CurrentIrql = 17;
  Pfn1 = 0i64;
  v16 = ((a8 & 2) != 0) + 1;
  v64 = v16;
  while( 2 )
  {
    v17 = (int)a6;
    v18 = 0;
    while( 1 )
    {
      v19 = 0;
      v20 = &v69;
      do
      {
        v21 = *(int *)v20;
        if( *(_QWORD *)&v13[8 * v21 + 16] || v14 == 1 && *(_QWORD *)&v13[8 * v21 + 32] )
          break;
        ++v19;
        v20 = (__int64 *)((char *)v20 + 4);
      }
      while( v19 < v16 );
      if( v19 != v16 )
        break;
      if( v18 != 1 )
      {
        if( (v10 & 0x10) == 0 )
          return 0i64;
        goto LABEL_28;
      }
      if( !*((_DWORD *)v12 + 1071) )
      {
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(CurrentIrql);
        return 0i64;
      }
      if( (v10 & 0x10) != 0 )
      {
        PcValue[1] = 0;
        v79[1] = (__int64)v79;
        v79[0] = (__int64)v79;
        v77 = *((_QWORD *)v12 + 536);
        *((_QWORD *)v12 + 536) = &v77;
        PcValue[0] = 393479;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(CurrentIrql);
        KeWaitForGate(PcValue, 18);
      }
      else
      {
        LODWORD(SpinCount) = 0;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        v11 = 2;
        __writecr8(CurrentIrql);
        if( a9 || CurrentIrql != 2 )
          return 0i64;
        LODWORD(SpinCount) = 0;
        while( *((_DWORD *)v12 + 1071) )
          KeYieldProcessorEx(&SpinCount);
      }
      v18 = 0;
LABEL_29:
      v13 = v66;
      v16 = v64;
      v14 = v70;
    }
    if( !v18 )
    {
LABEL_28:
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(2ui64);
      v18 = 1;
      KeAcquireInStackQueuedSpinLockAtDpcLevel((UINT64 *)v12 + 541, &LockHandle, v11);
      goto LABEL_29;
    }
    if( (_DWORD)a5 == 4 )
    {
      v22 = (char *)v12 + 4317;
      v23 = (char *)v12 + (unsigned int)MmNumberOfChannels + 4317;
    }
    else
    {
      v86 = a5;
      v22 = &v86;
      v23 = &v87;
    }
LABEL_31:
    v24 = (unsigned __int8)*v22;
    v25 = 0i64;
    Channel = v24;
    v67 = 0i64;
LABEL_32:
    v26 = 0;
    v27 = v24;
    v28 = &v69;
LABEL_33:
    v29 = *(int *)v28;
    v30 = 0;
    v72 = v17;
    v31 = v27 + 4 * (v29 + 2 * v25);
    while( 1 )
    {
      v32 = *(_QWORD *)&v66[32 * v31 + 560 + 8 * v17];
      if( *(_QWORD *)&v66[32 * v31 + 48 + 8 * v17] )
        break;
      v33 = v17;
      v34 = v17 + 1;
      v17 = 0i64;
      if( v33 != 3 )
        v17 = v34;
      ++v30;
      v72 = v17;
      if( v30 > 3 )
      {
        v25 = v67;
        ++v26;
        v28 = (__int64 *)((char *)v28 + 4);
        v72 = v17;
        v17 = (int)a6;
        if( v26 < v64 )
          goto LABEL_33;
        v24 = Channel;
        v17 = (int)a6;
        v25 = v67 + 1;
        v67 = v25;
        if( v25 <= v70 )
          goto LABEL_32;
        v17 = (int)a6;
        ++v22;
        v67 = v25;
        if( v22 != v23 )
          goto LABEL_31;
        break;
      }
    }
    v35 = LargePageIndex;
    v36 = HIDWORD(SpinCount);
    v37 = Channel;
    v38 = v72;
    v39 = (unsigned int)(*(_DWORD *)(a7 + 4i64 * LargePageIndex) % HIDWORD(SpinCount));
    v40 = v39;
    v81 = v29;
    v41 = (INT64 *)(v32 + 24 * v39);
    v42 = v72 + 4 * (Channel + 4 * (v29 + 2 * v67));
    v73 = v42;
    v43 = a9 == 0;
    while( 2 )
    {
      v63 = v43;
LABEL_43:
      v44 = 0;
      if( v36 )
      {
        do
        {
          if( (INT64 *)*v41 != v41 )
          {
            if( v63 || (*(_BYTE *)(v41[1] + 34) & 8) == 0 )
              break;
            v42 = v73;
          }
          v45 = v40 + 1;
          if( v40 + 1 == v36 )
            v41 = *(INT64 **)&v66[8 * v42 + 560];
          else
            v41 += 3;
          v40 = 0;
          ++v44;
          if( v45 != v36 )
            v40 = v45;
        }
        while( v44 < v36 );
        v10 = a8;
        v38 = v72;
        v43 = v63;
        v42 = v73;
      }
      if( v44 == v36 )
      {
        if( v43 )
          goto LABEL_85;
        v43 = 1;
        continue;
      }
      break;
    }
    v46 = v41[1];
    v47 = Pfn1;
    v48 = (volatile signed __int64 *)(v46 + 24);
    v49 = _interlockedbittestandset64((volatile signed __int32 *)(v46 + 24), 0x3Fui64);
    if( v47 )
    {
      if( v49 )
        goto LABEL_81;
      v50 = 1;
    }
    else
    {
      v50 = v49 == 0;
    }
    if( v50 )
    {
      if( a9 )
      {
        v46 = v41[1];
        v51 = *(INT64 ***)(v46 + 8);
        if( *(INT64 **)v46 != v41
          || *v51 != (INT64 *)v46
          || (v41[1] = (INT64)v51, *v51 = v41, v52 = (_QWORD *)*v41, *(INT64 **)(*v41 + 8) != v41) )
        {
          __fastfail(3u);
        }
        v53 = (RTL_BALANCED_NODE *)a9;
        *(_QWORD *)v46 = v52;
        *(_QWORD *)(v46 + 8) = v41;
        v52[1] = v46;
        *v41 = v46;
        if( !(unsigned int)MiBeginPageAccessor(v53, v46) )
LABEL_66:
          v46 = 0i64;
      }
      else
      {
        if( !MiUnlinkNodeLargePageHelper(NodeInformation, (_MMPFN *)v46, v35, v37) )
          goto LABEL_66;
        if( (v10 & 0x20) != 0 )
          ++*(_DWORD *)(v80 + *(_QWORD *)(a1 + 16) + 4284);
        *(_QWORD *)v46 = Pfn1;
      }
      if( !v46 )
      {
        _InterlockedAnd64(v48, 0x7FFFFFFFFFFFFFFFui64);
        break;
      }
      ++v40;
      v35 = LargePageIndex;
      v55 = a3 - 1;
      v54 = a3 == 1;
      Pfn1 = (_MMPFN *)v46;
      --a3;
      *(_DWORD *)(a7 + 4i64 * LargePageIndex) = v40;
      if( v54 )
        break;
      if( (v55 & 0xF) == 0 )
      {
        if( KeShouldYieldProcessor() )
          break;
        v35 = LargePageIndex;
      }
      v36 = HIDWORD(SpinCount);
      if( v40 == HIDWORD(SpinCount) )
      {
        v40 = 0;
        v37 = Channel;
        v41 = *(INT64 **)&v66[256 * v67 + 560 + 128 * v81 + 32 * Channel + 8 * v38];
        v43 = v63;
        v42 = v73;
      }
      else
      {
        v43 = v63;
        v41 += 3;
        v42 = v73;
        v37 = Channel;
      }
      goto LABEL_43;
    }
LABEL_81:
    if( !v47 )
    {
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      __writecr8(CurrentIrql);
      v12 = NodeInformation;
      v13 = v66;
      v16 = v64;
      v14 = v70;
      continue;
    }
    break;
  }
LABEL_85:
  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
  v56 = Pfn1;
  if( !Pfn1 )
    goto LABEL_91;
  while( 2 )
  {
    if( a9 )
    {
      v57 = 0i64;
      goto LABEL_88;
    }
    v57 = *(_MMPFN **)v56;
    if( *(_QWORD *)v56 )
      _InterlockedAnd64((volatile signed __int64 *)v56 + 3, 0x7FFFFFFFFFFFFFFFui64);
    else
LABEL_88:
      MiUnlockPage(v56, 2u);
    v56 = v57;
    if( v57 )
      continue;
    break;
  }
  v10 = a8;
  if( (a8 & 0x20) == 0 )
LABEL_91:
    __writecr8(CurrentIrql);
  v58 = Pfn1;
  if( Pfn1 && (v10 & 0x40) == 0 && (_DWORD)a6 != *((unsigned __int8 *)Pfn1 + 34) >> 6 )
  {
    v59 = v82;
    v60 = Pfn1;
    do
    {
      if( a9 )
        v61 = 0i64;
      else
        v61 = *(_MMPFN **)v60;
      MiChangePageAttributeContiguous((v60 - MmGetPfnDb()) / 48, v59, (unsigned int)a6);
      v75 = *((_QWORD *)v60 + 2);
      MiSetOriginalPtePfnFromFreeList(&v75);
      *((_QWORD *)v60 + 2) = v75;
      v60 = v61;
    }
    while( v61 );
  }
  return(INT64)v58;
}

Referenced by:

MiGetFreeZeroLargePages
MiGetHugePageToZero
MiGetPagesToZero
MiScrubNodeLargePageList
MiTimeSingleLargePageZeroWorker
MiZeroLargePages