MiUnlinkNodeLargePages

NTSTATUS __stdcall MiUnlinkNodeLargePages(
        INT64 a1,
        UINT64 a2,
        INT64 a3,
        UINT64 a4,
        INT64 a5,
        INT64 a6,
        INT64 a7,
        INT64 Channel,
        UINT64 Node){
  __int64 v9; 
  int v10; 
  _MI_NODE_INFORMATION *v11; 
  _MI_FREE_LARGE_PAGES *v12; 
  __int64 v13; 
  unsigned __int8 CurrentIrql; 
  unsigned int v15; 
  __int64 v16; 
  int v17; 
  unsigned int v18; 
  __int64 *v19; 
  __int64 v20; 
  char *LockedChannelOrdering; 
  char *v22; 
  CHAR v23; 
  unsigned int v24; 
  __int64 v25; 
  unsigned int v26; 
  __int64 v27; 
  __int64 *v28; 
  __int64 v29; 
  unsigned int v30; 
  __int64 v31; 
  _MI_FREE_LARGE_PAGE_LIST *v32; 
  __int64 v33; 
  __int64 v34; 
  unsigned int v35; 
  unsigned int v36; 
  unsigned int v37; 
  __int64 v38; 
  __int64 v39; 
  int v40; 
  INT64 *v41; 
  __int64 v42; 
  _BOOL4 v43; 
  unsigned int v44; 
  int v45; 
  INT64 v46; 
  _MMPFN *v47; 
  volatile signed __int64 *v48; 
  signed __int8 v49; 
  _BOOL4 v50; 
  INT64 **v51; 
  _QWORD *v52; 
  _RTL_BALANCED_NODE *v53; 
  bool v54; 
  char v55; 
  _MMPFN *v56; 
  _MMPFN *bf_0; 
  NTSTATUS v58; 
  INT64 v59; 
  _MMPFN *v60; 
  _MMPFN *v61; 
  UINT64 v63; 
  _BOOL4 v64; 
  unsigned int v65; 
  unsigned int v66; 
  _MI_FREE_LARGE_PAGES *v67; 
  __int64 v68; 
  UINT64 SpinCount; 
  __int64 v70; 
  __int64 v71; 
  _MMPFN *Pfn1; 
  __int64 v73; 
  __int64 v74; 
  _MI_NODE_INFORMATION *NodeInformation; 
  UINT64 Long; 
  _KLOCK_QUEUE_HANDLE LockHandle; 
  _MI_LARGE_PAGE_LISTS_CHANGING *LargeListWaiters; 
  int v79[2]; 
  __int64 v80[2]; 
  __int64 v81; 
  __int64 v82; 
  INT64 v83; 
  unsigned int LargePageIndex; 
  char v87; 
  char v88; 

  LargePageIndex = a2;
  v9 = *(_QWORD *)(a1 + 16);
  v10 = Channel;
  memset(&LockHandle, 0, sizeof(LockHandle));
  v11 = (_MI_NODE_INFORMATION *)(4544i64 * (unsigned int)a4 + v9);
  v87 = 0;
  v81 = 4544i64 * (unsigned int)a4;
  NodeInformation = v11;
  if( !v11->TotalPagesEntireNode && (MiFlags & 0x30) != 0 )
    return 0;
  v12 = &v11->FreeLargePages[(unsigned int)a2];
  v83 = MiLargePageSizes[(unsigned int)a2];
  HIDWORD(SpinCount) = *((_DWORD *)&stru_140C4DB30 + (unsigned int)a2 + 100);
  v67 = v12;
  if( (Channel & 4) != 0 )
    v70 = 0x100000000i64;
  else
    v70 = 1i64;
  v13 = (Channel & 1) == 0;
  v71 = v13;
  CurrentIrql = 17;
  Pfn1 = 0i64;
  v15 = ((Channel & 2) != 0) + 1;
  v65 = v15;
  while( 2 )
  {
    v16 = (int)a6;
    v17 = 0;
    while( 1 )
    {
      v18 = 0;
      v19 = &v70;
      do
      {
        v20 = *(int *)v19;
        if( v12->LargePageFreeCountHiLow[0][v20] || v13 == 1 && v12->LargePageFreeCountHiLow[1][v20] )
          break;
        ++v18;
        v19 = (__int64 *)((char *)v19 + 4);
      }
      while( v18 < v15 );
      if( v18 != v15 )
        break;
      if( v17 != 1 )
      {
        if( (v10 & 0x10) == 0 )
          return 0;
        goto LABEL_28;
      }
      if( !v11->LargeListMoveInProgress )
      {
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(CurrentIrql);
        return 0;
      }
      if( (v10 & 0x10) != 0 )
      {
        v79[1] = 0;
        v80[1] = (__int64)v80;
        v80[0] = (__int64)v80;
        LargeListWaiters = v11->LargeListWaiters;
        v11->LargeListWaiters = (_MI_LARGE_PAGE_LISTS_CHANGING *)&LargeListWaiters;
        v79[0] = 393479;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(CurrentIrql);
        KeWaitForGate((_KGATE *)v79, WrVirtualMemory, v23);
      }
      else
      {
        LODWORD(SpinCount) = 0;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(CurrentIrql);
        if( Node || CurrentIrql != 2 )
          return 0;
        LODWORD(SpinCount) = 0;
        while( v11->LargeListMoveInProgress )
          KeYieldProcessorEx(&SpinCount);
      }
      v17 = 0;
LABEL_29:
      v12 = v67;
      v15 = v65;
      v13 = v71;
    }
    if( !v17 )
    {
LABEL_28:
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(2ui64);
      v17 = 1;
      KeAcquireInStackQueuedSpinLockAtDpcLevel(&v11->LargePageLock, &LockHandle);
      goto LABEL_29;
    }
    if( (_DWORD)a5 == 4 )
    {
      LockedChannelOrdering = (char *)v11->LockedChannelOrdering;
      v22 = (char *)&v11->LockedChannelOrdering[MmNumberOfChannels];
    }
    else
    {
      v87 = a5;
      LockedChannelOrdering = &v87;
      v22 = &v88;
    }
LABEL_31:
    v24 = (unsigned __int8)*LockedChannelOrdering;
    v25 = 0i64;
    v66 = v24;
    v68 = 0i64;
LABEL_32:
    v26 = 0;
    v27 = v24;
    v28 = &v70;
LABEL_33:
    v29 = *(int *)v28;
    v30 = 0;
    v73 = v16;
    v31 = v27 + 4 * (v29 + 2 * v25);
    while( 1 )
    {
      v32 = v67->LargePageEntries[0][0][v31][v16];
      if( v67->LargePagesCount[0][0][v31][v16] )
        break;
      v33 = v16;
      v34 = v16 + 1;
      v16 = 0i64;
      if( v33 != 3 )
        v16 = v34;
      ++v30;
      v73 = v16;
      if( v30 > 3 )
      {
        v25 = v68;
        ++v26;
        v28 = (__int64 *)((char *)v28 + 4);
        v73 = v16;
        v16 = (int)a6;
        if( v26 < v65 )
          goto LABEL_33;
        v24 = v66;
        v16 = (int)a6;
        v25 = v68 + 1;
        v68 = v25;
        if( v25 <= v71 )
          goto LABEL_32;
        v16 = (int)a6;
        ++LockedChannelOrdering;
        v68 = v25;
        if( LockedChannelOrdering != v22 )
          goto LABEL_31;
        break;
      }
    }
    v35 = LargePageIndex;
    v36 = HIDWORD(SpinCount);
    v37 = v66;
    v38 = v73;
    v39 = (unsigned int)(*(_DWORD *)(a7 + 4i64 * LargePageIndex) % HIDWORD(SpinCount));
    v40 = v39;
    v82 = v29;
    v41 = (INT64 *)&v32[v39];
    v42 = v73 + 4 * (v66 + 4 * (v29 + 2 * v68));
    v74 = v42;
    v43 = Node == 0;
    while( 2 )
    {
      v64 = v43;
LABEL_43:
      v44 = 0;
      if( v36 )
      {
        do
        {
          if( (INT64 *)*v41 != v41 )
          {
            if( v64 || (*(_BYTE *)(v41[1] + 34) & 8) == 0 )
              break;
            v42 = v74;
          }
          v45 = v40 + 1;
          if( v40 + 1 == v36 )
            v41 = (INT64 *)v67->LargePageEntries[0][0][0][v42];
          else
            v41 += 3;
          v40 = 0;
          ++v44;
          if( v45 != v36 )
            v40 = v45;
        }
        while( v44 < v36 );
        v10 = Channel;
        v38 = v73;
        v43 = v64;
        v42 = v74;
      }
      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( Node )
      {
        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 *)Node;
        *(_QWORD *)v46 = v52;
        *(_QWORD *)(v46 + 8) = v41;
        v52[1] = v46;
        *v41 = v46;
        if( !MiBeginPageAccessor(v53, v46) )
LABEL_66:
          v46 = 0i64;
      }
      else
      {
        LODWORD(v63) = v10;
        if( !MiUnlinkNodeLargePageHelper(NodeInformation, (_MMPFN *)v46, v35, v37, v63) )
          goto LABEL_66;
        if( (v10 & 0x20) != 0 )
          ++*(_DWORD *)(v81 + *(_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( (unsigned int)KeShouldYieldProcessor() )
          break;
        v35 = LargePageIndex;
      }
      v36 = HIDWORD(SpinCount);
      if( v40 == HIDWORD(SpinCount) )
      {
        v40 = 0;
        v37 = v66;
        v41 = (INT64 *)v67->LargePageEntries[v68][v82][v66][v38];
        v43 = v64;
        v42 = v74;
      }
      else
      {
        v43 = v64;
        v41 += 3;
        v42 = v74;
        v37 = v66;
      }
      goto LABEL_43;
    }
LABEL_81:
    if( !v47 )
    {
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      __writecr8(CurrentIrql);
      v11 = NodeInformation;
      v12 = v67;
      v15 = v65;
      v13 = v71;
      continue;
    }
    break;
  }
LABEL_85:
  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
  v56 = Pfn1;
  if( !Pfn1 )
    goto LABEL_91;
  while( 2 )
  {
    if( Node )
    {
      bf_0 = 0i64;
      goto LABEL_88;
    }
    bf_0 = (_MMPFN *)v56->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0;
    if( v56->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 )
      _InterlockedAnd64(&v56->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
    else
LABEL_88:
      MiUnlockPage(v56, 2u);
    v56 = bf_0;
    if( bf_0 )
      continue;
    break;
  }
  LOBYTE(v10) = Channel;
  if( (Channel & 0x20) == 0 )
LABEL_91:
    __writecr8(CurrentIrql);
  v58 = (int)Pfn1;
  if( Pfn1 && (v10 & 0x40) == 0 && (_DWORD)a6 != *((unsigned __int8 *)&Pfn1->u3 + 2) >> 6 )
  {
    v59 = v83;
    v60 = Pfn1;
    do
    {
      if( Node )
        v61 = 0i64;
      else
        v61 = (_MMPFN *)v60->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0;
      MiChangePageAttributeContiguous(v60 - MmGetPfnDb(), v59, (unsigned int)a6);
      Long = v60->OriginalPte.u.Long;
      MiSetOriginalPtePfnFromFreeList(&Long);
      v60->OriginalPte.u.Long = Long;
      v60 = v61;
    }
    while( v61 );
  }
  return v58;
}

Referenced by:

MiGetFreeZeroLargePages
MiGetHugePageToZero
MiGetPagesToZero
MiScrubNodeLargePageList
MiTimeSingleLargePageZeroWorker
MiZeroLargePages