MiWsleFree

INT64 MiWsleFree(INT64 a1, UINT64 a2, CHAR a3, ...){
  _MMPTE *PteBase; 
  unsigned __int64 v4; 
  UINT64 v8; 
  unsigned __int64 v9; 
  _UNICODE_STRING *v10; 
  UINT8 v11; 
  wchar_t *v12; 
  _MMPFN *v13; 
  _MMPTE *PteLimit; 
  char v15; 
  int v16; 
  _UNICODE_STRING *v17; 
  UINT8 v18; 
  wchar_t *v19; 
  int v20; 
  unsigned __int64 v21; 
  unsigned __int64 v22; 
  int v23; 
  volatile signed __int32 *p_u2; 
  _MMPFN *PfnDb; 
  int v26; 
  __int64 v27; 
  int v28; 
  union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v29; 
  struct _KPRCB *CurrentPrcb; 
  union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v31; 
  _MI_ZERO_THREAD_CONTEXT *MmInternal; 
  _MMPTE *v33; 
  unsigned __int64 v34; 
  unsigned __int64 v35; 
  _MMPTE *v36; 
  _QWORD *v37; 
  _QWORD *v38; 
  char v39; 
  union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v40; 
  union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v41; 
  _MI_PARTITION *v42; 
  unsigned __int64 *v43; 
  unsigned __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  _MMPFN *v47; 
  __int64 v48; 
  __int64 v49; 
  char v50; 
  __int64 v51; 
  __int64 v52; 
  char v53; 
  UINT64 v54; 
  _MMPFN *v55; 
  char v56; 
  UINT64 SpinCount; 
  UINT64 v59; 
  _MI_PARTITION *v60; 
  __int64 v61[10]; 
  int v63; 
  unsigned __int16 v65; 
  unsigned __int64 v66; 
  va_list va1; 
  va_list va; 

  va_start(va1, a3);
  va_start(va, a3);
  v66 = va_arg(va1, _QWORD);
  PteBase = MmGetPteBase();
  v4 = v66;
  v8 = (UINT64)PteBase + ((a2 >> 9) & 0x7FFFFFFFF8i64);
  LODWORD(v9) = MI_READ_PTE_LOCK_FREE((INT64)va);
  v13 = &MmGetPfnDb()[(v9 >> 12) & 0xFFFFFFFFFi64];
  PteLimit = MmGetPteLimit();
  if( a2 < (unsigned __int64)PteBase || a2 > (unsigned __int64)PteLimit )
    v15 = HIBYTE(v4) & 0xF | (16 * ((v4 >> 60) & 7));
  else
    v15 = (v13->$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::gap0[0] >> 1) & 7;
  LOBYTE(v16) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v13, v10, v11, v12);
  v63 = v16;
  if( (a3 & 4) != 0 )
    goto LABEL_15;
  if( v16 )
  {
    if( (v13->u4._bf_0 & 0x1000000000i64) == 0 && (__int64)v13->ListEntry.Blink > 0
      || (*(_DWORD *)(&v13->3 + 1) & 0x400i64) != 0 )
    {
      goto LABEL_15;
    }
  }
  else
  {
    if( (*(_BYTE *)(a1 + 184) & 7u) >= 2 )
      goto LABEL_15;
    if( (MiGetPagePrivilege((ULONG_PTR)v13, 0i64, 0i64) & 0xFFFFFFFD) != 0 )
      goto LABEL_15;
    LOBYTE(v20) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v13, v17, v18, v19);
    if( !v20 )
    {
      v21 = (unsigned __int64)MmGetPteBase();
      v22 = (__int64)((v8 << 25) - (v21 << 25)) >> 16;
      if( v22 >= v21 && v22 <= (unsigned __int64)MmGetPteLimit() )
        goto LABEL_15;
    }
  }
  if( v13->u3.ReferenceCount != 1
    || (*(_BYTE *)(&v13->u3 + 1) & 0xC0) != 64
    || (v23 = 1, (*((_BYTE *)&v13->u3 + 3) & 0x40) != 0) )
  {
LABEL_15:
    v23 = 0;
  }
  p_u2 = (volatile signed __int32 *)&v13->u2;
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64(p_u2, 0x3Fui64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( *(__int64 *)p_u2 < 0 );
  }
  if( v23 )
  {
    if( (*(_QWORD *)p_u2 & 0x3FFFFFFFFFFFFFFFi64) != 1 || v13->u3.ReferenceCount != 1 )
      goto LABEL_46;
    PfnDb = MmGetPfnDb();
    v26 = 4;
    v27 = v13 - PfnDb;
    v28 = *((unsigned __int8 *)&PfnDb[v27].u3 + 2) >> 6;
    if( !v28 || v28 == 3 )
    {
      v26 = 12;
    }
    else if( v28 == 2 )
    {
      v26 = 28;
    }
    LODWORD(v29.Long) = MiMakeValidPte(0i64, v27, v26 | 0xA0000000);
    CurrentPrcb = KeGetCurrentPrcb();
    v31.Long = v29.Long;
    MmInternal = (_MI_ZERO_THREAD_CONTEXT *)CurrentPrcb->MmInternal;
    if( MmInternal )
    {
      MiGetUltraMapping(MmInternal + 3112, 3i64);
      v33 = MmGetPteBase();
      v35 = v34;
      v36 = (_MMPTE *)((char *)v33 + ((v34 >> 9) & 0x7FFFFFFFF8i64));
      *((_QWORD *)MmInternal + 1543) = v36;
      if( v34 )
      {
LABEL_36:
        if( v36 >= MmGetPml4eBase()
          && v36 <= MmGetPxeUserLimit()
          && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0
          && (v31.Long & 1) != 0 )
        {
          v31.Long |= 0x8000000000000000ui64;
        }
        v36->u.Long = v31.Long;
        v37 = (_QWORD *)v35;
        v38 = (_QWORD *)(v35 + 4088);
        do
        {
          if( *v37 | *v38 )
            break;
          ++v37;
          --v38;
        }
        while( v37 <= v38 );
        MiUnmapPageInHyperSpaceWorker((VOID *)v35, 0x11u, 0x80000000ui64);
        if( v37 > v38 )
        {
          MiRewriteTrimPteAsDemandZero(a1, (INT64)v13);
          goto LABEL_47;
        }
LABEL_46:
        v23 = 0;
        goto LABEL_47;
      }
    }
    else
    {
      v33 = MmGetPteBase();
    }
    v35 = ((unsigned __int64)CurrentPrcb->HyperPte & 0xFFFFFFFFFFFFF000ui64)
        + (((__int64)CurrentPrcb->HyperPte & 0xFFF) << 12);
    v36 = (_MMPTE *)((char *)v33 + ((v35 >> 9) & 0x7FFFFFFFF8i64));
    goto LABEL_36;
  }
LABEL_47:
  v39 = v66;
  v40.Long = 0i64;
  v60 = 0i64;
  if( v23 || (v66 & 4) != 0 )
  {
    LODWORD(v49) = MiGetContainingPageTable(v8);
    v50 = *((_BYTE *)&v13->u3 + 2);
    v51 = v49;
    v13->u4._bf_0 &= v52;
    *((_BYTE *)&v13->u3 + 2) = v50 & 0xC7;
    v53 = *((_BYTE *)&v13->u3 + 3);
    *(_QWORD *)p_u2 &= 0xC000000000000000ui64;
    *((_BYTE *)&v13->u3 + 3) = v53 & 0xDF;
    v13->u3.ReferenceCount = 0;
    v40.Long = MiCapturePageFileInfoInline(&v13->OriginalPte, 0i64, 0i64).u.Long;
    if( v40.Long )
      v42 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v13->u4._bf_0 >> 39) & 0x3FF));
    else
      v42 = v60;
    MiInsertPageInFreeOrZeroedList(
      v13 - MmGetPfnDb(),
      (unsigned int)((v39 & 4) != 0) + 1,
      (v39 & 4) != 0,
      v54,
      SpinCount,
      v59);
    _InterlockedAnd64((volatile signed __int64 *)p_u2, 0x7FFFFFFFFFFFFFFFui64);
    v55 = &MmGetPfnDb()[v51];
    LODWORD(v59) = 0;
    p_u2 = (volatile signed __int32 *)&v55->u2;
    while( _interlockedbittestandset64(p_u2, 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&v59);
      while( *(__int64 *)p_u2 < 0 );
    }
    MiDecrementShareCount(v55);
  }
  else
  {
    if( (v66 & 0x42) != 0 )
    {
      MiCaptureDirtyBitToPfn();
      v40.Long = v41.Long;
      if( v41.Long )
        v42 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v13->u4._bf_0 >> 39) & 0x3FF));
      else
        v42 = 0i64;
    }
    else
    {
      v42 = 0i64;
    }
    if( v63 )
    {
      v43 = (unsigned __int64 *)((char *)&MmGetPteBase()->u.Long + ((v8 >> 9) & 0x7FFFFFFFF8i64));
      v44 = *v43;
      MiPteInShadowRange((UINT64)v43);
      v61[0] = v44;
      MiPteInShadowRange((UINT64)v61);
      v45 = (v44 >> 12) & 0xFFFFFFFFFi64;
    }
    else
    {
      v45 = -1i64;
    }
    if( (a3 & 1) != 0
      && (*(_QWORD *)p_u2 & 0x3FFFFFFFFFFFFFFFi64) == 1
      && v13->u3.ReferenceCount == 1
      && (*(_BYTE *)(&v13->u3 + 1) & 0x10) == 0
      && MiGetPfnPriority(v13) == 5 )
    {
      *((_BYTE *)&v13->u3 + 3) = *((_BYTE *)&v13->u3 + 3) & 0xF8 | 4;
    }
    if( (*(_BYTE *)(&v13->u3 + 1) & 7) != 6 )
      MiBadShareCount();
    v46 = (*(_QWORD *)p_u2 & 0x3FFFFFFFFFFFFFFFi64) - 1;
    *(_QWORD *)p_u2 ^= (*(_QWORD *)p_u2 ^ v46) & 0x3FFFFFFFFFFFFFFFi64;
    if( !v46 )
      MiPfnShareCountIsZero(v13, 0i64);
    if( v45 != -1 )
    {
      _InterlockedAnd64((volatile signed __int64 *)p_u2, 0x7FFFFFFFFFFFFFFFui64);
      v47 = &MmGetPfnDb()[v45];
      HIDWORD(SpinCount) = 0;
      p_u2 = (volatile signed __int32 *)&v47->u2;
      while( _interlockedbittestandset64(p_u2, 0x3Fui64) )
      {
        do
          KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
        while( *(__int64 *)p_u2 < 0 );
      }
      if( (*(_BYTE *)(&v47->u3 + 1) & 7) != 6 )
        MiBadShareCount();
      v48 = (*(_QWORD *)p_u2 & 0x3FFFFFFFFFFFFFFFi64) - 1;
      *(_QWORD *)p_u2 ^= (*(_QWORD *)p_u2 ^ v48) & 0x3FFFFFFFFFFFFFFFi64;
      if( !v48 )
        MiPfnShareCountIsZero(v47, 0i64);
    }
  }
  _InterlockedAnd64((volatile signed __int64 *)p_u2, 0x7FFFFFFFFFFFFFFFui64);
  if( v40.Long )
    MiReleasePageFileInfo(v42, (_MMPTE)v40.Long, 1ui64);
  v56 = 1;
  LOBYTE(v65) = v15;
  if( !v63 )
    v56 = 3;
  HIBYTE(v65) = v56;
  return v65;
}

Referenced by:

MiFreeWsleList