MiCopyDataPageToImagePage

NTSTATUS __stdcall MiCopyDataPageToImagePage(
        _MMINPAGE_SUPPORT *InPageSupport,
        _SUBSECTION *Subsection,
        _MMPTE *ImageProtoPte,
        VOID *TrapInformation,
        UINT64 PageFrameIndex,
        _MMPFN *LockedProtoPfn){
  _MMINPAGE_SUPPORT *v8; 
  VOID *FaultingAddress; 
  unsigned int v10; 
  _CONTROL_AREA *ControlArea; 
  INT16 v12; 
  unsigned int v13; 
  _LARGE_INTEGER v14; 
  INT64 *p_ControlAreaLock; 
  _LARGE_INTEGER v16; 
  unsigned __int64 v17; 
  __int64 v18; 
  UINT64 v19; 
  _MMPFN *v20; 
  unsigned int v22; 
  unsigned __int64 v23; 
  unsigned __int64 v24; 
  __int64 v25; 
  unsigned int v26; 
  _MMPFN **v27; 
  __int64 v28; 
  unsigned __int64 v29; 
  __int64 v30; 
  unsigned __int64 v31; 
  _MMPFN *v32; 
  _MMPFN *v33; 
  _ETHREAD *CurrentThread; 
  _MMPFN **v35; 
  _MMPFN *v36; 
  char v37; 
  int v38; 
  _MI_RESAVAIL_CHARGE v39; 
  _MMPFN *v40; 
  _MMPFN **v41; 
  UINT64 v42; 
  _MMPFN *v43; 
  _MMPTE *v44; 
  char v45; 
  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;} v46; 
  _MMPFN *v47; 
  UINT64 v48; 
  UINT64 v49; 
  UINT64 v50; 
  __int64 v51; 
  __int64 v52; 
  __int64 v53; 
  int v54; 
  __int64 v55; 
  __int64 v56; 
  __int64 v57; 
  int v58; 
  __int64 v59; 
  __int64 v60; 
  int v61; 
  _KTBFLUSH_TYPE v62; 
  int v63; 
  _MMPFN *DecayPfn; 
  _MMPFN *v65; 
  _MMPFN *PfnDb; 
  UINT8 v67; 
  UINT8 v68; 
  UINT64 v69; 
  UINT8 v70; 
  unsigned int v71; 
  INT64 *SpinLock; 
  unsigned int NumberOfPtes; 
  _CONTROL_AREA *Src; 
  _ETHREAD *v75; 
  _LARGE_INTEGER v76; 
  PVOID LockedPfns; 
  UINT64 SpinCount; 
  _MMPFN *v79; 
  _MMPFN *Pfn1[10]; 
  unsigned __int64 v81; 
  UINT8 PageIrql; 
  _MMPTE *PointerPte; 
  unsigned __int64 v85; 

  v85 = (unsigned __int64)TrapInformation;
  PointerPte = ImageProtoPte;
  PageIrql = 0;
  v8 = InPageSupport;
  memset(Pfn1, 0i64, sizeof(Pfn1));
  FaultingAddress = v8->FaultingAddress;
  LOBYTE(v10) = 0;
  v79 = 0i64;
  ControlArea = Subsection->ControlArea;
  Src = Subsection->ControlArea;
  MiGetSessionIdForVa(FaultingAddress, v12);
  v14.anonymous_0.LowPart = MiStartingOffset(Subsection, ImageProtoPte, v13);
  p_ControlAreaLock = (INT64 *)&ControlArea->ControlAreaLock;
  v76 = v14;
  SpinLock = (INT64 *)&ControlArea->ControlAreaLock;
  v16 = v14;
  ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&ControlArea->ControlAreaLock);
  v17 = ControlArea->FilePointer.Value & 0xFFFFFFFFFFFFFFF0ui64;
  ExAcquireSpinLockExclusiveAtDpcLevel(&::SpinLock);
  v18 = **(_QWORD **)(v17 + 40);
  if( !v18 || !(unsigned int)ExTryAcquireSpinLockExclusiveAtDpcLevel((INT64 *)(v18 + 72)) )
  {
    ExReleaseSpinLockExclusiveFromDpcLevel(&::SpinLock);
LABEL_3:
    if( (v10 & 1) != 0 )
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v18 + 72));
    if( (v10 & 2) == 0 )
      ExReleaseSpinLockExclusiveFromDpcLevel(p_ControlAreaLock);
    if( Pfn1[5] )
      _InterlockedAnd64(&Pfn1[5]->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
    if( Pfn1[6] )
      MiUnlockNestedProtoPoolPage(Pfn1[6]);
    v20 = Pfn1[0];
    if( BYTE1(Pfn1[4]) == 1 )
      MiRemoveLockedPageChargeAndDecRef(Pfn1[0]);
    if( v20 )
      _InterlockedAnd64(&v20->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
    if( Pfn1[1] )
      MiUnlockProtoPoolPage((ULONG_PTR)Pfn1[1], 2u);
    if( (v10 & 4) != 0 )
      MiDereferenceControlAreaPfnList(Src, 0i64, v19, 3ui64);
    return 0;
  }
  ExReleaseSpinLockExclusiveFromDpcLevel(&::SpinLock);
  v19 = 0i64;
  LOBYTE(v10) = 1;
  if( !*(_QWORD *)(v18 + 32) || (*(_DWORD *)(v18 + 56) & 3) != 0 )
    goto LABEL_3;
  MiEndingOffset(Subsection);
  v81 = v23;
  v24 = (unsigned __int64)v16.QuadPart >> 12;
  v10 = v22 + 8;
  v25 = v18 + 128;
  if( (unsigned int)((unsigned __int64)v16.QuadPart >> 12) != (unsigned int)((v23 - 1) >> 12) )
    v10 = v22;
  while( 1 )
  {
    v26 = *(_DWORD *)(v25 + 44);
    if( (unsigned int)v24 < v26 )
      break;
    v25 = *(_QWORD *)(v25 + 16);
    LODWORD(v24) = v24 - v26;
    if( !v25 )
      goto LABEL_3;
  }
  v27 = Pfn1;
  NumberOfPtes = 2;
  while( 1 )
  {
    if( *(_DWORD *)(v25 + 104) == (_DWORD)v19 )
      goto LABEL_90;
    v28 = *(_QWORD *)(v25 + 8);
    if( !v28 )
      goto LABEL_90;
    v29 = v28 + 8i64 * (unsigned int)v24;
    if( !v29 )
      goto LABEL_90;
    v30 = (v29 >> 9) & 0x7FFFFFFFF8i64;
    v31 = ((unsigned __int64)PointerPte >> 9) & 0x7FFFFFFFF8i64;
    v27[2] = (_MMPFN *)v29;
    if( v30 == v31 || v27 != Pfn1 && v30 == (((unsigned __int64)*(v27 - 3) >> 9) & 0x7FFFFFFFF8i64) )
    {
      MiTryLockLeafPage((_MMPTE *)v29, 0x7FFFFFFFF8ui64);
    }
    else
    {
      if( (int)MiTryLockProtoPoolPageAtDpc((_MMPTE *)v29, 0x7FFFFFFFF8ui64) < 0 )
        goto LABEL_90;
      v27[1] = v79;
    }
    v32 = *v27;
    if( !*v27
      || (*(_BYTE *)(&v32->u3 + 1) & 0x20) != 0
      || (*((_BYTE *)&v32->u3 + 3) & 0x40) != 0
      || v32->u3.ReferenceCount >= 0x7FFFu )
    {
      goto LABEL_90;
    }
    LODWORD(v33) = MI_READ_PTE_LOCK_FREE(v29);
    v27[3] = v33;
    if( v27 != Pfn1 || (v76.anonymous_0.LowPart & 0xFFF) == 0 || v10 >= 8 )
      break;
    v27 += 5;
    ++NumberOfPtes;
    LODWORD(v24) = v24 + 1;
    v19 = 0i64;
    if( (unsigned int)v24 >= *(_DWORD *)(v25 + 44) )
    {
      v25 = *(_QWORD *)(v25 + 16);
      LODWORD(v24) = 0;
      if( !v25 )
        goto LABEL_90;
    }
  }
  ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v18 + 72));
  ++Src->NumberOfPfnReferences;
  ExReleaseSpinLockExclusiveFromDpcLevel(SpinLock);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v35 = Pfn1;
  v36 = Pfn1[0];
  LOBYTE(v10) = v10 & 0xF8 | 6;
  v75 = CurrentThread;
  LockedPfns = Pfn1[0];
  if( !Pfn1[0] )
    goto LABEL_55;
  while( 1 )
  {
    v37 = 0;
    if( ((_BYTE)v35[3] & 1) == 0 && !v36->u3.ReferenceCount )
    {
      *((_BYTE *)v35 + 32) = (*((_BYTE *)&v36->u3 + 3) & 8) != 0;
      MiUnlinkPageFromList(v36, 0i64);
      if( !v38 )
      {
        MiDiscardTransitionPteEx(v36, 0i64);
LABEL_90:
        p_ControlAreaLock = SpinLock;
        goto LABEL_3;
      }
      v37 = 1;
      v36->u2._bf_0 &= 0xC000000000000000ui64;
    }
    v39 = MiAddLockedPageCharge(v36, 0i64);
    v19 = 0i64;
    if( v39 == MiChargeFailed )
    {
      if( v37 )
        MiPfnReferenceCountIsZero(v36, v36 - MmGetPfnDb(), 0);
      goto LABEL_90;
    }
    *((_BYTE *)v35 + 33) = 1;
    if( v35 != Pfn1 )
      break;
    v35 += 5;
    v36 = *v35;
    LockedPfns = v36;
    if( !v36 )
      goto LABEL_54;
  }
  _InterlockedAnd64(&v36->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  v40 = v35[1];
  if( v40 )
  {
    MiUnlockNestedProtoPoolPage(v40);
    v35[1] = 0i64;
  }
LABEL_54:
  CurrentThread = v75;
LABEL_55:
  v8->u1.e1._bf_0 |= 0x20u;
  v41 = Pfn1;
  _InterlockedAnd64(&Pfn1[0]->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  if( Pfn1[1] )
    MiUnlockProtoPoolPage((ULONG_PTR)Pfn1[1], 2u);
  v42 = PageFrameIndex;
  v43 = &MmGetPfnDb()[PageFrameIndex];
  LODWORD(SpinCount) = 0;
  if( _interlockedbittestandset64((volatile signed __int32 *)&v43->u2, 0x3Fui64) )
  {
    do
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( v43->u2._bf_0 < 0 );
    }
    while( _interlockedbittestandset64((volatile signed __int32 *)&v43->u2, 0x3Fui64) );
    CurrentThread = v75;
  }
  v44 = PointerPte;
  MiInitializeTransitionPfn(v42, PointerPte);
  v45 = *(_BYTE *)(&v43->u3 + 1) & 0xF8 | 2;
  *((_BYTE *)&v43->u3 + 2) = v45;
  v43->u3.ReferenceCount = 1;
  *((_BYTE *)&v43->u3 + 2) = v45 | 0x20;
  v43->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = (__int64)&v8->ListHead[1];
  if( (v85 & 1) != 0 && *(_BYTE *)(v85 & 0xFFFFFFFFFFFFFFFEui64) == 1 )
  {
    MiAdvanceFaultList((_MI_FAULT_VA_LIST *)(v85 & 0xFFFFFFFFFFFFFFFEui64));
    v8->u1.e1._bf_0 |= 8u;
  }
  *((_BYTE *)&v43->u3 + 3) ^= (*((_BYTE *)&v43->u3 + 3) ^ ((unsigned __int32)v8->u1.e1._bf_0 >> 9)) & 7;
  _InterlockedAnd64(&v43->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  LODWORD(v46.Long) = MI_READ_PTE_LOCK_FREE((INT64)v44);
  v8->PteContents.u = (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;})v46.Long;
  v8->PointerPte = v44;
  if( PsGetIoPriorityThread(CurrentThread) < IoPriorityNormal )
    v8->u1.e1._bf_0 |= 0x80u;
  v47 = LockedProtoPfn;
  v8->Mdl.Next = 0i64;
  v8->Mdl.StartVa = 0i64;
  *(_DWORD *)&v8->Mdl.Size = 56;
  *(_QWORD *)&v8->Mdl.ByteCount = 4096i64;
  v8->Page[0] = v42;
  MiObtainProtoReference(v47, 0i64);
  MiUnlockProtoPoolPage((ULONG_PTR)v47, 2u);
  v8->Mdl.MdlFlags |= 0x42u;
  v8->Pfn = v43;
  v8->ControlArea = Src;
  v8->ReadOffset = v76;
  v8->BasePte = v44;
  v8->FilePointer = 0i64;
  v8->LockedProtoPfn = v47;
  v48 = (UINT64)MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), NumberOfPtes);
  v50 = v48;
  if( v48 )
  {
    v51 = (__int64)((v48 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
    LODWORD(v52) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v48, v42, 2684354564i64);
    v53 = v52;
    LOBYTE(v54) = MiPteInShadowRange(v50);
    if( v54 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v53 & 1) != 0 )
      v53 |= v55;
    *(_QWORD *)v50 = v53;
    LODWORD(v56) = MiMakeValidPte((_XSTATE_CONFIGURATION *)(v50 + 8), Pfn1[0] - MmGetPfnDb(), 536870913i64);
    v57 = v56;
    LOBYTE(v58) = MiPteInShadowRange(v50 + 8);
    if( v58 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v57 & 1) != 0 )
      v57 |= 0x8000000000000000ui64;
    *(_QWORD *)(v50 + 8) = v57;
    if( Pfn1[5] )
    {
      LODWORD(v59) = MiMakeValidPte((_XSTATE_CONFIGURATION *)(v50 + 16), Pfn1[5] - MmGetPfnDb(), 536870913i64);
      v60 = v59;
      LOBYTE(v61) = MiPteInShadowRange(v50 + 16);
      if( v61 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v60 & 1) != 0 )
        v60 |= 0x8000000000000000ui64;
      *(_QWORD *)(v50 + 16) = v60;
    }
    if( v76.QuadPart + 4096 > v81 )
    {
      v71 = ((_WORD)v81 - LOWORD(v76.anonymous_0.LowPart)) & 0xFFF;
      memmove((VOID *)v51, (const VOID *)(v51 + (v76.anonymous_0.LowPart & 0xFFF) + 4096i64), v71);
      memset((VOID *)(v71 + v51), 0i64, 4096 - v71);
    }
    else
    {
      KeCopyPage((PVOID)v51);
    }
    MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), (_MMPTE *)v50, NumberOfPtes, v62);
    __incgsdword(0x2E98u);
    v47 = LockedProtoPfn;
    v63 = 0;
  }
  else
  {
    v63 = -1073741670;
  }
  v8->IoStatus.Status = v63;
  DecayPfn = 0i64;
  if( LOBYTE(Pfn1[4]) || LOBYTE(Pfn1[9]) )
    DecayPfn = MiCreateDecayPfn(v49);
  v65 = Pfn1[0];
  LockedPfns = Pfn1[0];
  if( Pfn1[0] )
  {
    PfnDb = MmGetPfnDb();
    while( 1 )
    {
      PageIrql = MiLockPageInline(v65);
      v67 = PageIrql;
      if( !MiRemoveLockedPageCharge(v65) )
        goto LABEL_77;
      if( !DecayPfn || !*((_BYTE *)v41 + 32) || (v65->u2._bf_0 & 0x4000000000000000i64) != 0 )
        break;
      LOBYTE(v69) = v67;
      MiInsertAndUnlockStandbyPages(DecayPfn, &LockedPfns, (UINT8 *)1, v69);
      PageIrql = 17;
LABEL_79:
      if( v41 == Pfn1 )
      {
        v41 += 5;
        v65 = *v41;
        LockedPfns = v65;
        if( v65 )
          continue;
      }
      v8 = InPageSupport;
      v47 = LockedProtoPfn;
      goto LABEL_82;
    }
    MiPfnReferenceCountIsZero(v65, v65 - PfnDb, v68);
LABEL_77:
    if( v67 != 17 )
    {
      _InterlockedAnd64(&v65->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
      __writecr8(PageIrql);
    }
    goto LABEL_79;
  }
LABEL_82:
  if( DecayPfn )
    MiDecayPfnFullyInitialized(DecayPfn);
  MiRelockProtoPoolPage(v47, &PageIrql);
  v70 = PageIrql;
  v8->u1.e1._bf_0 &= ~0x20u;
  MiUnlockProtoPoolPage((ULONG_PTR)v47, v70);
  v8->IoStatus.Information = 4096i64;
  KeSetEvent((PRKEVENT)&v8->ListHead[1], 0, 0);
  return 1;
}

Referenced by:

MiResolveMappedFileFault