MmUnlockPages

VOID __stdcall MmUnlockPages(_MDL *MemoryDescriptorList){
  __int16 MdlFlags; 
  unsigned __int64 *v2; 
  unsigned int ByteOffset; 
  char *StartVa; 
  __int64 ByteCount; 
  _MMPTE *PteBase; 
  unsigned __int64 v8; 
  void *MappedSystemVa; 
  unsigned int v10; 
  unsigned int v11; 
  char *v12; 
  __int64 v13; 
  unsigned __int64 v14; 
  unsigned __int64 v15; 
  unsigned __int64 v16; 
  unsigned __int64 v17; 
  int v18; 
  __int64 v19; 
  _QWORD *v20; 
  _MMPTE *v21; 
  _CONTROL_AREA *v22; 
  unsigned __int64 v23; 
  int v24; 
  unsigned __int64 v25; 
  int v26; 
  INT64 v27; 
  INT64 CurrentIrql; 
  unsigned __int64 v29; 
  UINT8 v30; 
  char *v31; 
  __int64 v32; 
  _MMPFN *PfnDb; 
  INT64 v34; 
  unsigned __int64 v35; 
  int v36; 
  _CONTROL_AREA *v37; 
  __int64 v38; 
  _MMPFN *BaseResidentPage; 
  INT64 v40; 
  char v41; 
  __int64 v42; 
  int v43; 
  __int64 v44; 
  UINT64 v45; 
  bool v46; 
  __int16 v47; 
  struct _KPRCB *CurrentPrcb; 
  __int64 v49; 
  __int64 v50; 
  int v51; 
  _MMPTE *v52; 
  char v53; 
  int v54; 
  int v55; 
  unsigned __int64 v56; 
  unsigned __int64 v57; 
  __int64 v58; 
  __int64 v59; 
  __int64 v60; 
  __int64 v61; 
  signed __int32 v62; 
  __int64 v63; 
  unsigned __int8 v64; 
  char *v65; 
  __int64 v66; 
  unsigned __int64 v67; 
  unsigned __int64 v68; 
  _MMPTE *PteLimit; 
  unsigned __int64 v70; 
  int v71; 
  unsigned __int64 v72; 
  UINT64 v73; 
  __int64 v74; 
  __int64 v75; 
  unsigned __int64 v76; 
  struct _KPRCB *v77; 
  __int64 v78; 
  signed __int32 v79; 
  ULONG_PTR BugCheckParameter4; 
  INT64 v81; 
  _MDL *a7; 
  UINT64 v83; 
  INT64 a9; 
  INT64 a10; 
  INT64 v86; 
  INT64 a12; 
  __int64 v88; 
  unsigned __int64 v89; 
  __int64 v90; 
  _EPROCESS *Process; 
  unsigned __int64 v92; 
  unsigned __int64 v93; 
  unsigned __int64 v94; 
  __int64 v95; 
  __int16 v97; 
  int v98; 
  UINT64 SpinCount; 
  MdlFlags = MemoryDescriptorList->MdlFlags;
  v2 = (unsigned __int64 *)&MemoryDescriptorList[1];
  Process = MemoryDescriptorList->Process;
  v97 = MdlFlags;
  a7 = MemoryDescriptorList + 1;
  if( (MdlFlags & 0x200) != 0 )
    MiRetardMdl(MemoryDescriptorList);
  ByteOffset = MemoryDescriptorList->ByteOffset;
  StartVa = (char *)MemoryDescriptorList->StartVa;
  ByteCount = MemoryDescriptorList->ByteCount;
  PteBase = MmGetPteBase();
  v8 = ((unsigned __int64)(((_WORD)StartVa + (_WORD)ByteOffset) & 0xFFF) + ByteCount + 4095) >> 12;
  v89 = v8;
  if( (MdlFlags & 1) != 0 )
  {
    MappedSystemVa = MemoryDescriptorList->MappedSystemVa;
    v10 = 0;
    if( (MemoryDescriptorList->MdlFlags & 0x200) != 0 )
    {
      v11 = MiRetardMdl(MemoryDescriptorList);
      ByteOffset = MemoryDescriptorList->ByteOffset;
      v10 = v11;
      StartVa = (char *)MemoryDescriptorList->StartVa;
      LODWORD(ByteCount) = MemoryDescriptorList->ByteCount;
    }
    v12 = &StartVa[ByteOffset];
    v13 = ((_WORD)StartVa + (_WORD)ByteOffset) & 0xFFF;
    v14 = (v13 + (unsigned __int64)(unsigned int)ByteCount + 4095) >> 12;
    if( (unsigned __int64)MappedSystemVa > 0x7FFFFFFEFFFFi64 )
    {
      v15 = (unsigned __int64)MappedSystemVa - v10;
      MemoryDescriptorList->MdlFlags &= 0xFFDEu;
      v16 = (unsigned __int64)PteBase + ((v15 >> 9) & 0x7FFFFFFFF8i64);
      if( (MemoryDescriptorList->MdlFlags & 4) != 0 )
        MemoryDescriptorList->MappedSystemVa = v12;
      v92 = (unsigned __int64)PteBase + ((v15 >> 9) & 0x7FFFFFFFF8i64);
      v17 = v92;
      v18 = 4;
      v93 = (unsigned __int64)PteBase + ((v16 >> 9) & 0x7FFFFFFFF8i64);
      v94 = (unsigned __int64)PteBase + ((v93 >> 9) & 0x7FFFFFFFF8i64);
      v19 = 4i64;
      v95 = (__int64)PteBase + ((v94 >> 9) & 0x7FFFFFFFF8i64);
      do
      {
        v20 = *(&Process + v19--);
        --v18;
        if( (*v20 & 1) == 0 )
          break;
        if( (*v20 & 0x80u) != 0i64 )
          goto LABEL_15;
      }
      while( v19 != 1 );
      v18 = 0;
LABEL_15:
      if( v18 )
      {
        v21 = MmGetPteBase();
        do
        {
          v17 = (unsigned __int64)v21 + ((v17 >> 9) & 0x7FFFFFFFF8i64);
          --v18;
        }
        while( v18 );
      }
      if( (*(_QWORD *)v17 & 0x200i64) != 0 )
        MiZeroAndFlushPtes(v15, v14);
      if( MmProtectFreedNonPagedPool == 1 )
        ++v14;
      if( (dword_140CFA17C & 1) != 0 )
        MiRemovePteTracker(MemoryDescriptorList, (PVOID)v15, v14);
      MiReleasePtes((INT64)&qword_140C4EC80, v16, (unsigned int)v14);
      v8 = v89;
    }
    else
    {
      MiUnmapLockedPagesInUserSpace(
        MappedSystemVa,
        (MDL *)((v13 + (unsigned __int64)(unsigned int)ByteCount + 4095) >> 12));
    }
    v2 = (unsigned __int64 *)a7;
  }
  if( (MmTrackLockedPages & 1) != 0 )
    MiFreeMdlTracker(MemoryDescriptorList, v8);
  v22 = 0i64;
  v23 = (unsigned __int64)&v2[v8];
  v24 = 1;
  v88 = 0i64;
  a12 = v23;
  v25 = 0i64;
  v98 = 1;
  v26 = 1;
  a9 = 0xFFFFFFFFFi64;
  v27 = 0xFFFFFFFFFi64;
  CurrentIrql = KeGetCurrentIrql();
  a10 = CurrentIrql;
  __writecr8(2ui64);
  do
  {
    v29 = *v2;
    v30 = 0;
    v31 = (char *)MmGetPfnDb() + 40;
    if( *v2 == -1i64 )
      break;
    v32 = 0xFFFFFFFFFi64;
    if( v29 > 0xFFFFFFFFFi64 || (*(_QWORD *)&v31[48 * v29] & 0x4000000000000i64) == 0 )
    {
      MiDereferenceIoPages(0i64, v29, 1i64);
      goto LABEL_123;
    }
    PfnDb = MmGetPfnDb();
    v90 = 48 * v29;
    v34 = (INT64)PfnDb + 48 * v29;
    if( (MdlFlags & 0x100) != 0 )
    {
      v35 = *(_QWORD *)(v34 + 40);
      if( (v35 & 0x1000000000i64) == 0 && ((v35 >> 60) & 7) != 1 )
      {
        v29 = 0xFFFFFFFFDi64;
        if( (v35 & 0xFFFFFFFFFi64) != 0xFFFFFFFFDi64 && v27 != (v35 & 0xFFFFFFFFFi64) )
        {
          if( v27 != 0xFFFFFFFFFi64 )
          {
            MiUnlockPageTableCharges((_MMPFN *)((char *)PfnDb + 48 * v27), v26, 0x1000000000ui64);
            v35 = *(_QWORD *)(v34 + 40);
          }
          a9 = v35 & 0xFFFFFFFFFi64;
          LOBYTE(v36) = MI_PFN_IS_PROTO((UNICODE_STRING *)v34, (UNICODE_STRING *)v29, v30, (PWCHAR)0xFFFFFFFFFi64);
          v98 = 2 - (v36 != 0);
        }
      }
    }
    LODWORD(SpinCount) = (_DWORD)v22;
    v37 = v22;
    v38 = (__int64)v22;
    BaseResidentPage = (_MMPFN *)v22;
    if( _interlockedbittestandset64((volatile signed __int32 *)(v34 + 24), 0x3Fui64) )
    {
      do
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( *(__int64 *)(v34 + 24) < 0 );
      }
      while( _interlockedbittestandset64((volatile signed __int32 *)(v34 + 24), 0x3Fui64) );
      v22 = 0i64;
    }
    v40 = *(_QWORD *)(qword_140C4E388 + 8 * ((*(_QWORD *)(v34 + 40) >> 39) & 0x3FFi64));
    v41 = *(_BYTE *)(v34 + 34);
    if( (v41 & 0x20) != 0 && (v41 & 8) == 0 && (*(_QWORD *)(v34 + 24) & 0x3FFFFFFFFFFFFFFFi64) == 0 )
    {
      v38 = *(_QWORD *)v34 - 32i64;
      _InterlockedDecrement64((volatile signed __int64 *)(v38 + 264));
    }
    if( (MdlFlags & 0x80u) != 0 )
    {
      if( !v38 )
      {
        v42 = *(_QWORD *)(v34 + 16);
        if( (v42 & 0x400) == 0 && (*(_BYTE *)(v34 + 34) & 8) == 0 )
        {
          if( (v42 & 4) != 0 )
          {
            v25 = MI_READ_PTE_LOCK_FREE(v34 + 16) & 0xFFFFFFFFFFFFFFFDui64;
            *(_QWORD *)(v34 + 16) = v42 & 0xFFFFFFFFFFFFFFFBui64;
          }
          else
          {
            v25 = (unsigned __int64)v22;
          }
        }
        v37 = (_CONTROL_AREA *)BaseResidentPage;
        *(_BYTE *)(v34 + 34) |= 0x10u;
      }
      if( (*(_QWORD *)(v34 + 40) & 0x1000000000i64) == 0 )
      {
        LOBYTE(v43) = MI_PFN_IS_PROTO((UNICODE_STRING *)v34, (UNICODE_STRING *)v29, v30, (PWCHAR)v32);
        if( v43 )
        {
          v44 = *(_QWORD *)(v34 + 16);
          if( (v44 & 0x400) != 0 )
          {
            if( qword_140C4DC80 && (v44 & 0x10) == 0 )
              v44 &= ~qword_140C4DC80;
            v37 = *(_CONTROL_AREA **)(v44 >> 16);
          }
        }
      }
    }
    v45 = *(unsigned __int16 *)(v34 + 32);
    if( !(_WORD)v45 )
      MiBadRefCount((_MMPFN *)v34, v45);
    v46 = (_WORD)v45 == 1;
    v47 = v45 - 1;
    *(_WORD *)(v34 + 32) = v47;
    if( !v46 || !MiIsPfnFileOnly(v34) )
    {
      v49 = *(_QWORD *)(v34 + 40);
      if( (v49 & 0x1000000000i64) != 0 || (v49 & 0x2000000000000i64) != 0 )
        goto LABEL_107;
      v50 = *(_QWORD *)(v34 + 24) & 0x3FFFFFFFFFFFFFFFi64;
      if( v47 )
      {
        if( v47 != 1 )
        {
          if( v47 != 2 || !v50 )
            goto LABEL_107;
          goto LABEL_74;
        }
        if( !v50 )
        {
LABEL_74:
          if( (*(_BYTE *)(v34 + 34) & 8) == 0 )
            goto LABEL_107;
        }
        v51 = 0;
      }
      else
      {
        v51 = 1;
      }
      v52 = MmGetPteBase();
      v32 = (__int64)v52 + 0x3FFFFFFF78i64;
      CurrentPrcb = (struct _KPRCB *)(*(_QWORD *)(v34 + 8) | 0x8000000000000000ui64);
      if( CurrentPrcb > (struct _KPRCB *)((char *)v52 + 0x3FFFFFFF78i64) || CurrentPrcb < (struct _KPRCB *)v52 )
      {
        v53 = *(_BYTE *)(v34 + 35);
        if( (v53 & 0x20) != 0 )
        {
          *(_BYTE *)(v34 + 35) = v53 & 0xDF;
          goto LABEL_105;
        }
      }
      LOBYTE(v54) = MI_PFN_IS_PROTO((UNICODE_STRING *)v34, 0i64, *(_BYTE *)(v34 + 8), (PWCHAR)v32);
      if( v54 && (*(_DWORD *)(v34 + 16) & 0x400i64) != 0 )
      {
        v55 = 1;
      }
      else if( (unsigned __int64)CurrentPrcb <= v56
             && CurrentPrcb >= (struct _KPRCB *)MmGetPteBase()
             && (*(_BYTE *)(v34 + 35) & 0x20) != 0 )
      {
        v55 = 1;
      }
      else if( v51 == 1 && (v58 & 0x4000000000000000i64) != 0 )
      {
        v55 = 1;
      }
      v59 = (v57 >> 39) & 0x3FF;
      v60 = *(_QWORD *)(qword_140C4E388 + 8 * v59);
      if( v55 == 1 )
        MiReturnCommit(*(_MI_PARTITION **)(qword_140C4E388 + 8 * v59), 1ui64);
      v32 = 1i64;
      if( (ULONG_PTR *)v60 == &MiSystemPartition )
      {
        CurrentPrcb = KeGetCurrentPrcb();
        v61 = *((int *)CurrentPrcb + 8391);
        if( (_DWORD)v61 != -1 )
        {
          if( (unsigned __int64)(v61 + 1) <= 0x100 )
          {
            while( 1 )
            {
              v62 = _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, v61 + 1, v61);
              v46 = (_DWORD)v61 == v62;
              LODWORD(v61) = v62;
              if( v46 )
                break;
              if( v62 == -1 || (unsigned __int64)(v62 + 1i64) > 0x100 )
                goto LABEL_99;
            }
LABEL_105:
            if( !v51 )
              goto LABEL_107;
            goto LABEL_106;
          }
LABEL_99:
          if( (int)v61 > 192
            && (_DWORD)v61 != -1
            && (_DWORD)v61 == _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, 192, v61) )
          {
            v32 = (int)v61 - 192 + 1i64;
          }
          if( !v32 )
            goto LABEL_105;
        }
      }
      v32 = _InterlockedExchangeAdd64((volatile signed __int64 *)(v60 + 7168), v32);
      goto LABEL_105;
    }
LABEL_106:
    MiPfnReferenceCountIsZero((_MMPFN *)v34, v90 / 48, (UINT8 *)CurrentPrcb);
LABEL_107:
    if( (*(_QWORD *)(v34 + 40) & 0x1000000000i64) != 0
      && (*(_QWORD *)(v34 + 24) & 0x4000000000000000i64) != 0
      && *(_WORD *)(v34 + 32) == 2 )
    {
      *(_QWORD *)(v34 + 24) &= ~0x4000000000000000ui64;
      BaseResidentPage = MiGetBaseResidentPage((_MMPFN *)v34);
      v63 = (*(_QWORD *)BaseResidentPage & 0xFFFFFFFFFi64) - 1;
      *(_QWORD *)BaseResidentPage ^= (v63 ^ *(_QWORD *)BaseResidentPage) & 0xFFFFFFFFFi64;
      if( BaseResidentPage != (_MMPFN *)v34 )
        _InterlockedAnd64((volatile signed __int64 *)BaseResidentPage + 3, 0x7FFFFFFFFFFFFFFFui64);
      if( v63 )
        BaseResidentPage = 0i64;
    }
    _InterlockedAnd64((volatile signed __int64 *)(v34 + 24), 0x7FFFFFFFFFFFFFFFui64);
    if( v25 )
    {
      MiReleasePageFileInfo(v40, v25, 1, v32, BugCheckParameter4, v81, (INT64)a7, v83, a9, a10, v86, a12);
      v25 = 0i64;
    }
    if( BaseResidentPage )
      MiFinishLargePageFree((INT64)BaseResidentPage, 1ui64);
    if( v37 )
      MiDereferenceControlAreaProbe(v37, (_BYTE *)1);
    if( (ULONG_PTR *)v40 != &MiSystemPartition )
      ExReleaseRundownProtectionCacheAware(*(PEX_RUNDOWN_REF_CACHE_AWARE *)(v40 + 2144));
    MdlFlags = v97;
    LOBYTE(CurrentIrql) = a10;
    v23 = a12;
    v2 = (unsigned __int64 *)a7;
    v27 = a9;
LABEL_123:
    a7 = (_MDL *)++v2;
    if( (++v88 & 0x3F) == 0 && (unsigned __int8)CurrentIrql < 2u )
    {
      if( (unsigned __int64)v2 >= v23 )
      {
        v26 = v98;
        break;
      }
      if( KeShouldYieldProcessor() )
      {
        __writecr8((unsigned __int8)CurrentIrql);
        v64 = KeGetCurrentIrql();
        __writecr8(2ui64);
        LOBYTE(CurrentIrql) = v64;
        a10 = v64;
      }
    }
    v26 = v98;
    v22 = 0i64;
  }
  while( (unsigned __int64)v2 < v23 );
  if( v27 != 0xFFFFFFFFFi64 )
  {
    v65 = (char *)MmGetPfnDb() + 48 * v27;
    v66 = 0i64;
    if( v26 == 2 )
    {
      if( (v65[34] & 7) != 6
        || (*((_QWORD *)v65 + 3) & 0x3FFFFFFFFFFFFFFFi64) == 0
        || (v67 = *((_QWORD *)v65 + 1) | 0x8000000000000000ui64, v68 = (unsigned __int64)MmGetPteBase(), v67 < v68)
        || (PteLimit = MmGetPteLimit(), v67 > (unsigned __int64)PteLimit)
        || (v70 = (__int64)((v67 << 25) - (v68 << 25)) >> 16, v70 < v68)
        || v70 > (unsigned __int64)PteLimit )
      {
        v24 = 0;
      }
      v71 = 3;
      if( v24 )
        goto LABEL_145;
      goto LABEL_179;
    }
    v71 = 1;
    if( !v26 )
      v71 = 4;
LABEL_145:
    if( (*((_QWORD *)v65 + 3) & 0x3FFFFFFFFFFFFFFFui64) < 0x10000 )
LABEL_179:
      KeBugCheckEx(
        0x1Au,
        0x41791ui64,
        (ULONG_PTR)v65,
        *((_QWORD *)v65 + 1) | 0x8000000000000000ui64,
        *((_QWORD *)v65 + 3) & 0x3FFFFFFFFFFFFFFFi64);
    v72 = 0i64;
    v73 = 0i64;
    while( 1 )
    {
      v74 = *((_QWORD *)v65 + 5) & 0xFFFFFFFFFi64;
      LODWORD(v83) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)v65 + 6, 0x3Fui64) )
      {
        do
          KeYieldProcessorEx(&v83);
        while( *((__int64 *)v65 + 3) < 0 );
      }
      v75 = *((_QWORD *)v65 + 3) ^ ((*((_QWORD *)v65 + 3) - 0x10000i64) ^ *((_QWORD *)v65 + 3)) & 0x3FFFFFFFFFFFFFFFi64;
      *((_QWORD *)v65 + 3) = v75;
      v76 = v75 & 0x3FFFFFFFFFFFFFFFi64;
      if( v76 >= 0x10000 )
        break;
      if( !v66 )
        v66 = *(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)v65 + 5) >> 39) & 0x3FFi64));
      ++v72;
      if( !v76 && (unsigned int)MiPfnShareCountIsZero((UINT64)v65, 0i64) != 3 )
        ++v73;
      _InterlockedAnd64((volatile signed __int64 *)v65 + 3, 0x7FFFFFFFFFFFFFFFui64);
      if( !--v71 )
        goto LABEL_159;
      v65 = (char *)MmGetPfnDb() + 48 * v74;
    }
    _InterlockedAnd64((volatile signed __int64 *)v65 + 3, 0x7FFFFFFFFFFFFFFFui64);
LABEL_159:
    if( v72 )
    {
      if( (ULONG_PTR *)v66 == &MiSystemPartition )
      {
        v77 = KeGetCurrentPrcb();
        v78 = *((int *)v77 + 8391);
        if( (_DWORD)v78 != -1 )
        {
          if( v72 + v78 <= 0x100 )
          {
            do
            {
              if( v72 >= 0x80000 )
                break;
              v79 = _InterlockedCompareExchange((volatile signed __int32 *)v77 + 8391, v72 + v78, v78);
              v46 = (_DWORD)v78 == v79;
              LODWORD(v78) = v79;
              if( v46 )
                goto LABEL_173;
            }
            while( v79 != -1 && v72 + v79 <= 0x100 );
          }
          if( (int)v78 > 192
            && (_DWORD)v78 != -1
            && (_DWORD)v78 == _InterlockedCompareExchange((volatile signed __int32 *)v77 + 8391, 192, v78) )
          {
            v72 += (int)v78 - 192;
          }
        }
      }
      if( v72 )
        _InterlockedExchangeAdd64((volatile signed __int64 *)(v66 + 7168), v72);
    }
LABEL_173:
    if( v73 )
      MiReturnCommit((_MI_PARTITION *)v66, v73);
  }
  __writecr8((unsigned __int8)CurrentIrql);
  if( Process )
    _InterlockedExchangeAdd64((volatile signed __int64 *)Process + 160, -(__int64)v89);
  MemoryDescriptorList->MdlFlags &= 0xF6FDu;
}

Referenced by:

AlpcpFreeCompletionList
AlpcpInitializeCompletionList
CcCopyBytesToUserBuffer
CcLockSystemCacheBuffer
CcMapAndCopyInToCache
CcMdlReadComplete2
CcMdlWriteAbort
CcMdlWriteComplete2
CcZeroDataInCache
ExUnlockUserBuffer
ExpGetLookasideInformation
ExpProfileDelete
FsRtlpFreeMdlChain
IopCleanupFileObjectIosbRange
IopSetFileObjectIosbRange
IopfCompleteRequest
KiOpPatchCode
MiAllocatePerSessionProtos
MiApplyImageHotPatch
MiCopyPagesIntoEnclave
MiGetWorkingSetInfo
MiGetWorkingSetInfoList
MiLoadDataIntoVsmEnclave
MiLoadSectionIntoVsmEnclave
MiProbeAndLockComplete
MiProbeAndLockPages
MiQueryMemoryPhysicalContiguity
MiReleaseHotPatchResources
MmCopyVirtualMemory
MmRotatePhysicalView
NT_DISK::Read
NT_DISK::Write
NtLoadEnclaveData
NtPssCaptureVaSpaceBulk
NtStartProfile
NtStopProfile
PopReadPagesFromHiberFile
PspCreateSecureThread
PspExitThread
PspGetSetContextInternal
PspIumAllocatePartitionState
PspIumFreePartitionState
SmPrepareForFatalPageError
SmProcessStatsRequest
VmProbeAndLockPages
VmUnlockPages
VslCallEnclave
VslFinalizeSecureImageHash
VslObtainHotPatchUndoTable
VslValidateDynamicCodePages
VslpLockPagesForTransfer
VslpUnlockPagesForTransfer
WbMakeUserDataPagesKernelWritable
WbMakeUserExecutablePagesKernelWritable
sub_14064F46C