Home | Info | Community | Development | myReactOS | Contact Us
Definition at line 1727 of file pagepae.c.
{ ULONG Attributes; PVOID Addr; ULONG i; ULONG oldPdeOffset, PdeOffset; BOOLEAN NoExecute = FALSE; DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n", Process, Address, flProtect, Pages, *Pages, PageCount); if (Process == NULL) { if (Address < MmSystemRangeStart) { DPRINT1("No process\n"); ASSERT(FALSE); } if (PageCount > 0x10000 || (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000) { DPRINT1("Page count to large\n"); ASSERT(FALSE); } } else { if (Address >= MmSystemRangeStart) { DPRINT1("Setting kernel address with process context\n"); ASSERT(FALSE); } if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE || (ULONG_PTR) Address / PAGE_SIZE + PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE) { DPRINT1("Page Count to large\n"); ASSERT(FALSE); } } Attributes = ProtectToPTE(flProtect); if (Attributes & 0x80000000) { NoExecute = TRUE; } Attributes &= 0xfff; if (Address >= MmSystemRangeStart) { Attributes &= ~PA_USER; if (Ke386GlobalPagesEnabled) { Attributes |= PA_GLOBAL; } } else { Attributes |= PA_USER; } Addr = Address; if (Ke386Pae) { ULONGLONG Pte, tmpPte; PULONGLONG Pt = NULL; oldPdeOffset = PAE_ADDR_TO_PDE_OFFSET(Addr) + 1; for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE)) { if (!(Attributes & PA_PRESENT) && Pages[i] != 0) { DPRINT1("Setting physical address but not allowing access at address " "0x%.8X with attributes %x/%x.\n", Addr, Attributes, flProtect); ASSERT(FALSE); } PdeOffset = PAE_ADDR_TO_PDE_OFFSET(Addr); if (oldPdeOffset != PdeOffset) { MmUnmapPageTable((PULONG)Pt); Pt = MmGetPageTableForProcessForPAE(Process, Addr, TRUE); if (Pt == NULL) { ASSERT(FALSE); } } else { Pt++; } oldPdeOffset = PdeOffset; MmMarkPageMapped(Pages[i]); tmpPte = PAE_PFN_TO_PTE(Pages[i]) | Attributes; if (NoExecute) { tmpPte |= 0x8000000000000000LL; } Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte); if (PAE_PAGE_MASK((Pte)) != 0LL && !((Pte) & PA_PRESENT)) { ASSERT(FALSE); } if (PAE_PAGE_MASK((Pte)) != 0LL) { MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte))); } if (Address < MmSystemRangeStart && ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL && Attributes & PA_PRESENT) { PUSHORT Ptrc; Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; Ptrc[PAE_ADDR_TO_PAGE_TABLE(Addr)]++; } if (Pte != 0LL) { if (Address > MmSystemRangeStart || (Pt >= (PULONGLONG)PAGETABLE_MAP && Pt < (PULONGLONG)PAGETABLE_MAP + 4*512*512)) { MiFlushTlb((PULONG)Pt, Address); } } } if (Addr > Address) { MmUnmapPageTable((PULONG)Pt); } } else { PULONG Pt = NULL; ULONG Pte; oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1; for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE)) { if (!(Attributes & PA_PRESENT) && Pages[i] != 0) { DPRINT1("Setting physical address but not allowing access at address " "0x%.8X with attributes %x/%x.\n", Addr, Attributes, flProtect); ASSERT(FALSE); } PdeOffset = ADDR_TO_PDE_OFFSET(Addr); if (oldPdeOffset != PdeOffset) { MmUnmapPageTable(Pt); Pt = MmGetPageTableForProcess(Process, Addr, TRUE); if (Pt == NULL) { ASSERT(FALSE); } } else { Pt++; } oldPdeOffset = PdeOffset; Pte = *Pt; MmMarkPageMapped(Pages[i]); if (PAGE_MASK((Pte)) != 0 && !((Pte) & PA_PRESENT)) { ASSERT(FALSE); } if (PAGE_MASK((Pte)) != 0) { MmMarkPageUnmapped(PTE_TO_PFN((Pte))); } (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes); if (Address < MmSystemRangeStart && ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL && Attributes & PA_PRESENT) { PUSHORT Ptrc; Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++; } if (Pte != 0) { if (Address > MmSystemRangeStart || (Pt >= (PULONG)PAGETABLE_MAP && Pt < (PULONG)PAGETABLE_MAP + 1024*1024)) { MiFlushTlb(Pt, Address); } } } if (Addr > Address) { MmUnmapPageTable(Pt); } } return(STATUS_SUCCESS); }