Home | Info | Community | Development | myReactOS | Contact Us
Definition at line 767 of file page.c.
{ ULONG Attributes; PVOID Addr; ULONG i; ULONG oldPdeOffset, PdeOffset; PULONG Pt = NULL; ULONG Pte; DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n", Process, Address, flProtect, Pages, *Pages, PageCount); ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0); if (Process == NULL) { if (Address < MmSystemRangeStart) { DPRINT1("No process\n"); KeBugCheck(MEMORY_MANAGEMENT); } if (PageCount > 0x10000 || (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000) { DPRINT1("Page count too large\n"); KeBugCheck(MEMORY_MANAGEMENT); } } else { if (Address >= MmSystemRangeStart) { DPRINT1("Setting kernel address with process context\n"); KeBugCheck(MEMORY_MANAGEMENT); } if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE || (ULONG_PTR) Address / PAGE_SIZE + PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE) { DPRINT1("Page Count too large\n"); KeBugCheck(MEMORY_MANAGEMENT); } } Attributes = ProtectToPTE(flProtect); Attributes &= 0xfff; if (Address >= MmSystemRangeStart) { Attributes &= ~PA_USER; } else { Attributes |= PA_USER; } Addr = Address; /* MmGetPageTableForProcess should be called on the first run, so * let this trigger it */ 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); KeBugCheck(MEMORY_MANAGEMENT); } PdeOffset = ADDR_TO_PDE_OFFSET(Addr); if (oldPdeOffset != PdeOffset) { if(Pt) MmUnmapPageTable(Pt); Pt = MmGetPageTableForProcess(Process, Addr, TRUE); if (Pt == NULL) { KeBugCheck(MEMORY_MANAGEMENT); } } else { Pt++; } oldPdeOffset = PdeOffset; Pte = InterlockedExchangePte(Pt, PFN_TO_PTE(Pages[i]) | Attributes); /* There should not be anything valid here */ if (Pte != 0) { DPRINT1("Bad PTE %lx\n", Pte); KeBugCheck(MEMORY_MANAGEMENT); } /* We don't need to flush the TLB here because it only caches valid translations * and we're moving this PTE from invalid to valid so it can't be cached right now */ if (Addr < MmSystemRangeStart) { /* Add PDE reference */ Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Addr)]++; ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Addr)] <= PTE_COUNT); } } ASSERT(Addr > Address); MmUnmapPageTable(Pt); return(STATUS_SUCCESS); }