MiCopyDataPageToImagePage

INT64 __fastcall MiCopyDataPageToImagePage(
        _MMINPAGE_SUPPORT *InPageSupport,
        _SUBSECTION *Subsection,
        _MMPTE *ImageProtoPte,
        VOID *TrapInformation,
        UINT64 PageFrameIndex,
        _MMPFN *LockedProtoPfn){
  _MMINPAGE_SUPPORT *v8; 
  void *v9; 
  unsigned int v10; 
  _CONTROL_AREA *v11; 
  unsigned int SessionIdForVa; 
  unsigned __int64 v13; 
  INT64 *v14; 
  unsigned __int64 v15; 
  unsigned __int64 v16; 
  __int64 v17; 
  UINT64 v18; 
  UINT64 v19; 
  ULONG_PTR v20; 
  unsigned int v22; 
  unsigned __int64 v23; 
  __int64 v24; 
  unsigned int v25; 
  ULONG_PTR *p_BugCheckParameter2; 
  __int64 v27; 
  unsigned __int64 v28; 
  __int64 v29; 
  unsigned __int64 v30; 
  _MMPFN *v31; 
  _ETHREAD *CurrentThread; 
  ULONG_PTR *v33; 
  UINT64 v34; 
  char v35; 
  int locked; 
  _MMPFN *v37; 
  ULONG_PTR *v38; 
  UINT64 v39; 
  char *v40; 
  MMPTE *v41; 
  char v42; 
  _MMPFN *v43; 
  UINT64 v44; 
  INT64 v45; 
  INT64 v46; 
  __int64 v47; 
  int v48; 
  _MMPFN *DecayPfn; 
  INT64 v50; 
  _MMPFN *PfnDb; 
  UINT8 v52; 
  UINT8 *v53; 
  UINT64 v54; 
  UINT64 v55; 
  unsigned int v56; 
  INT64 *SpinLock; 
  unsigned int v58; 
  _CONTROL_AREA *Src; 
  _ETHREAD *v60; 
  unsigned __int64 v61; 
  _MMPFN *LockedPfns; 
  UINT64 SpinCount; 
  _MMPFN *a3; 
  ULONG_PTR BugCheckParameter2; 
  _MMPFN *ProtoPagePfn; 
  char v67; 
  char v68; 
  __int64 v69; 
  _MMPFN *v70; 
  char v71; 
  UINT64 v72; 
  UINT8 v74; 
  MMPTE *PointerPte; 
  unsigned __int64 v76; 
  v76 = (unsigned __int64)TrapInformation;
  PointerPte = ImageProtoPte;
  v74 = 0;
  v8 = InPageSupport;
  memset((INT64)&BugCheckParameter2, 0i64);
  v9 = (void *)*((_QWORD *)v8 + 28);
  LOBYTE(v10) = 0;
  a3 = 0i64;
  v11 = *(_CONTROL_AREA **)Subsection;
  Src = *(_CONTROL_AREA **)Subsection;
  SessionIdForVa = MiGetSessionIdForVa(v9);
  v13 = MiStartingOffset((__int64)Subsection, (unsigned __int64)ImageProtoPte, SessionIdForVa);
  v14 = (INT64 *)((char *)v11 + 72);
  v61 = v13;
  SpinLock = (INT64 *)((char *)v11 + 72);
  v15 = v13;
  ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)v11 + 9);
  v16 = *((_QWORD *)v11 + 8) & 0xFFFFFFFFFFFFFFF0ui64;
  ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&dword_140C4C6C0);
  v17 = **(_QWORD **)(v16 + 40);
  if( !v17 || !(unsigned int)ExTryAcquireSpinLockExclusiveAtDpcLevel((INT64 *)(v17 + 72)) )
  {
    ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&dword_140C4C6C0);
LABEL_3:
    if( (v10 & 1) != 0 )
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v17 + 72));
    if( (v10 & 2) == 0 )
      ExReleaseSpinLockExclusiveFromDpcLevel(v14);
    if( v69 )
      _InterlockedAnd64((volatile signed __int64 *)(v69 + 24), 0x7FFFFFFFFFFFFFFFui64);
    if( v70 )
      MiUnlockNestedProtoPoolPage(v70);
    v20 = BugCheckParameter2;
    if( v68 == 1 )
      MiRemoveLockedPageChargeAndDecRef((_MMPFN *)BugCheckParameter2);
    if( v20 )
      _InterlockedAnd64((volatile signed __int64 *)(v20 + 24), 0x7FFFFFFFFFFFFFFFui64);
    if( ProtoPagePfn )
    {
      LOBYTE(v18) = 2;
      MiUnlockProtoPoolPage(ProtoPagePfn, v18);
    }
    if( (v10 & 4) != 0 )
      MiDereferenceControlAreaPfnList(Src, 0i64, v19, 3ui64);
    return 0i64;
  }
  ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&dword_140C4C6C0);
  v19 = 0i64;
  LOBYTE(v10) = 1;
  if( !*(_QWORD *)(v17 + 32) || (*(_DWORD *)(v17 + 56) & 3) != 0 )
    goto LABEL_3;
  v72 = MiEndingOffset(Subsection);
  v23 = v15 >> 12;
  v10 = v22 + 8;
  v24 = v17 + 128;
  if( (unsigned int)(v15 >> 12) != (unsigned int)((v72 - 1) >> 12) )
    v10 = v22;
  while( 1 )
  {
    v25 = *(_DWORD *)(v24 + 44);
    if( (unsigned int)v23 < v25 )
      break;
    v24 = *(_QWORD *)(v24 + 16);
    LODWORD(v23) = v23 - v25;
    if( !v24 )
      goto LABEL_3;
  }
  p_BugCheckParameter2 = &BugCheckParameter2;
  v58 = 2;
  while( 1 )
  {
    if( *(_DWORD *)(v24 + 104) == (_DWORD)v19 )
      goto LABEL_87;
    v27 = *(_QWORD *)(v24 + 8);
    v18 = 0x7FFFFFFFF8i64;
    if( !v27 )
      goto LABEL_87;
    v28 = v27 + 8i64 * (unsigned int)v23;
    if( !v28 )
      goto LABEL_87;
    v29 = (v28 >> 9) & 0x7FFFFFFFF8i64;
    v30 = ((unsigned __int64)PointerPte >> 9) & 0x7FFFFFFFF8i64;
    p_BugCheckParameter2[2] = v28;
    if( v29 == v30
      || p_BugCheckParameter2 != &BugCheckParameter2 && v29 == ((*(p_BugCheckParameter2 - 3) >> 9) & 0x7FFFFFFFF8i64) )
    {
      MiTryLockLeafPage((_MMPTE *)v28, 0x7FFFFFFFF8ui64);
    }
    else
    {
      if( (int)MiTryLockProtoPoolPageAtDpc((INT64 *)v28, 0x7FFFFFFFF8i64, &a3, (_MMPFN **)p_BugCheckParameter2) < 0 )
        goto LABEL_87;
      p_BugCheckParameter2[1] = (ULONG_PTR)a3;
    }
    v31 = (_MMPFN *)*p_BugCheckParameter2;
    if( !*p_BugCheckParameter2
      || (*((_BYTE *)v31 + 34) & 0x20) != 0
      || (*((_BYTE *)v31 + 35) & 0x40) != 0
      || *((_WORD *)v31 + 16) >= 0x7FFFu )
    {
      goto LABEL_87;
    }
    p_BugCheckParameter2[3] = MI_READ_PTE_LOCK_FREE(v28);
    if( p_BugCheckParameter2 != &BugCheckParameter2 || (v61 & 0xFFF) == 0 || v10 >= 8 )
      break;
    p_BugCheckParameter2 += 5;
    ++v58;
    LODWORD(v23) = v23 + 1;
    v19 = 0i64;
    if( (unsigned int)v23 >= *(_DWORD *)(v24 + 44) )
    {
      v24 = *(_QWORD *)(v24 + 16);
      LODWORD(v23) = 0;
      if( !v24 )
        goto LABEL_87;
    }
  }
  ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v17 + 72));
  ++*((_QWORD *)Src + 4);
  ExReleaseSpinLockExclusiveFromDpcLevel(SpinLock);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v33 = &BugCheckParameter2;
  v34 = BugCheckParameter2;
  LOBYTE(v10) = v10 & 0xF8 | 6;
  v60 = CurrentThread;
  LockedPfns = (_MMPFN *)BugCheckParameter2;
  if( !BugCheckParameter2 )
    goto LABEL_55;
  while( 1 )
  {
    v35 = 0;
    if( (v33[3] & 1) == 0 && !*(_WORD *)(v34 + 32) )
    {
      *((_BYTE *)v33 + 32) = (*(_BYTE *)(v34 + 35) & 8) != 0;
      if( !(unsigned int)MiUnlinkPageFromList((_MMPFN *)v34, 0i64) )
      {
        MiDiscardTransitionPteEx(v34, 0i64);
LABEL_87:
        v14 = SpinLock;
        goto LABEL_3;
      }
      v35 = 1;
      *(_QWORD *)(v34 + 24) &= 0xC000000000000000ui64;
    }
    locked = MiAddLockedPageCharge(v34, 0);
    v19 = 0i64;
    if( !locked )
    {
      if( v35 )
        MiPfnReferenceCountIsZero((_MMPFN *)v34, (__int64)(v34 - (_QWORD)MmGetPfnDb()) / 48, 0i64);
      goto LABEL_87;
    }
    *((_BYTE *)v33 + 33) = 1;
    if( v33 != &BugCheckParameter2 )
      break;
    v33 += 5;
    v34 = *v33;
    LockedPfns = (_MMPFN *)v34;
    if( !v34 )
      goto LABEL_54;
  }
  _InterlockedAnd64((volatile signed __int64 *)(v34 + 24), 0x7FFFFFFFFFFFFFFFui64);
  v37 = (_MMPFN *)v33[1];
  if( v37 )
  {
    MiUnlockNestedProtoPoolPage(v37);
    v33[1] = 0i64;
  }
LABEL_54:
  CurrentThread = v60;
LABEL_55:
  *((_DWORD *)v8 + 48) |= 0x20u;
  v38 = &BugCheckParameter2;
  _InterlockedAnd64((volatile signed __int64 *)(BugCheckParameter2 + 24), 0x7FFFFFFFFFFFFFFFui64);
  if( ProtoPagePfn )
  {
    LOBYTE(v18) = 2;
    MiUnlockProtoPoolPage(ProtoPagePfn, v18);
  }
  v39 = PageFrameIndex;
  v40 = (char *)MmGetPfnDb() + 48 * PageFrameIndex;
  LODWORD(SpinCount) = 0;
  if( _interlockedbittestandset64((volatile signed __int32 *)v40 + 6, 0x3Fui64) )
  {
    do
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( *((__int64 *)v40 + 3) < 0 );
    }
    while( _interlockedbittestandset64((volatile signed __int32 *)v40 + 6, 0x3Fui64) );
    CurrentThread = v60;
  }
  v41 = PointerPte;
  MiInitializeTransitionPfn(v39, PointerPte);
  v42 = v40[34] & 0xF8 | 2;
  v40[34] = v42;
  *((_WORD *)v40 + 16) = 1;
  v40[34] = v42 | 0x20;
  *(_QWORD *)v40 = (char *)v8 + 32;
  if( (v76 & 1) != 0 && *(_BYTE *)(v76 & 0xFFFFFFFFFFFFFFFEui64) == 1 )
  {
    MiAdvanceFaultList((_QWORD *)(v76 & 0xFFFFFFFFFFFFFFFEui64));
    *((_DWORD *)v8 + 48) |= 8u;
  }
  v40[35] ^= (v40[35] ^ (*((_DWORD *)v8 + 48) >> 9)) & 7;
  _InterlockedAnd64((volatile signed __int64 *)v40 + 3, 0x7FFFFFFFFFFFFFFFui64);
  *((_QWORD *)v8 + 21) = MI_READ_PTE_LOCK_FREE((INT64)v41);
  *((_QWORD *)v8 + 29) = v41;
  if( (int)PsGetIoPriorityThread((__int64)CurrentThread) < 2 )
    *((_DWORD *)v8 + 48) |= 0x80u;
  v43 = LockedProtoPfn;
  *((_QWORD *)v8 + 34) = 0i64;
  *((_QWORD *)v8 + 38) = 0i64;
  *((_DWORD *)v8 + 70) = 56;
  *((_QWORD *)v8 + 39) = 4096i64;
  *((_QWORD *)v8 + 40) = v39;
  MiObtainProtoReference((INT64)v43, 0);
  LOBYTE(v44) = 2;
  MiUnlockProtoPoolPage(v43, v44);
  *((_WORD *)v8 + 141) |= 0x42u;
  *((_QWORD *)v8 + 31) = v40;
  *((_QWORD *)v8 + 26) = Src;
  *((_QWORD *)v8 + 12) = v61;
  *((_QWORD *)v8 + 30) = v41;
  *((_QWORD *)v8 + 25) = 0i64;
  *((_QWORD *)v8 + 20) = v43;
  v45 = MiReservePtes((INT64)&qword_140C4EC80, v58);
  v46 = v45;
  if( v45 )
  {
    v47 = ((v45 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
    *(_QWORD *)v45 = MiMakeValidPte(v45, v39, 2684354564i64);
    *(_QWORD *)(v46 + 8) = MiMakeValidPte(
                             v46 + 8,
                             (__int64)(BugCheckParameter2 - (_QWORD)MmGetPfnDb()) / 48,
                             536870913i64);
    if( v69 )
      *(_QWORD *)(v46 + 16) = MiMakeValidPte(v46 + 16, (v69 - (__int64)MmGetPfnDb()) / 48, 536870913i64);
    if( v61 + 4096 > v72 )
    {
      v56 = ((_WORD)v72 - (_WORD)v61) & 0xFFF;
      memmove((UINT8 *)v47, (UINT8 *)(v47 + (v61 & 0xFFF) + 4096), ((_WORD)v72 - (_WORD)v61) & 0xFFF);
      memset(v56 + v47, 0i64);
    }
    else
    {
      KeCopyPage((PVOID)v47);
    }
    MiReleasePtes((INT64)&qword_140C4EC80, v46, v58);
    __incgsdword(0x2E98u);
    v43 = LockedProtoPfn;
    v48 = 0;
  }
  else
  {
    v48 = -1073741670;
  }
  *((_DWORD *)v8 + 20) = v48;
  DecayPfn = 0i64;
  if( v67 || v71 )
    DecayPfn = (_MMPFN *)MiCreateDecayPfn();
  v50 = BugCheckParameter2;
  LockedPfns = (_MMPFN *)BugCheckParameter2;
  if( BugCheckParameter2 )
  {
    PfnDb = MmGetPfnDb();
    while( 1 )
    {
      v74 = MiLockPageInline(v50);
      v52 = v74;
      if( !(unsigned int)MiRemoveLockedPageCharge(v50) )
        goto LABEL_74;
      if( !DecayPfn || !*((_BYTE *)v38 + 32) || (*(_QWORD *)(v50 + 24) & 0x4000000000000000i64) != 0 )
        break;
      LOBYTE(v54) = v52;
      MiInsertAndUnlockStandbyPages(DecayPfn, &LockedPfns, (UINT8 *)1, v54);
      v74 = 17;
LABEL_76:
      if( v38 == &BugCheckParameter2 )
      {
        v38 += 5;
        v50 = *v38;
        LockedPfns = (_MMPFN *)v50;
        if( v50 )
          continue;
      }
      v8 = InPageSupport;
      v43 = LockedProtoPfn;
      goto LABEL_79;
    }
    MiPfnReferenceCountIsZero((_MMPFN *)v50, (v50 - (__int64)PfnDb) / 48, v53);
LABEL_74:
    if( v52 != 17 )
    {
      _InterlockedAnd64((volatile signed __int64 *)(v50 + 24), 0x7FFFFFFFFFFFFFFFui64);
      __writecr8(v74);
    }
    goto LABEL_76;
  }
LABEL_79:
  if( DecayPfn )
    MiDecayPfnFullyInitialized((CHAR *)DecayPfn);
  MiRelockProtoPoolPage((INT64)v43, &v74);
  LOBYTE(v55) = v74;
  *((_DWORD *)v8 + 48) &= ~0x20u;
  MiUnlockProtoPoolPage(v43, v55);
  *((_QWORD *)v8 + 11) = 4096i64;
  KeSetEvent((PRKEVENT)((char *)v8 + 32), 0);
  return 1i64;
}

Referenced by:

MiResolveMappedFileFault