NTAPI
MmTrimAllSystemPageableMemory(IN ULONG PurgeTransitionList)
{
- UNIMPLEMENTED;
- return 0;
+ UNIMPLEMENTED;
+ return 0;
}
/*
//
if (TagToFree && TagToFree != Entry->PoolTag)
{
- DPRINT1("Freeing pool - invalid tag specified: %.4s != %.4s\n", (char*)&TagToFree, (char*)&Entry->PoolTag);
- KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, Entry->PoolTag, TagToFree);
+ DPRINT1("Freeing pool - invalid tag specified: %.4s != %.4s\n", (char*)&TagToFree, (char*)&Entry->PoolTag);
+ KeBugCheckEx(BAD_POOL_CALLER, 0x0A, (ULONG_PTR)P, Entry->PoolTag, TagToFree);
}
//
#if DBG
#define ASSERT_LIST_INVARIANT(x) \
do { \
- ASSERT(((x)->Total == 0 && \
+ ASSERT(((x)->Total == 0 && \
(x)->Flink == LIST_HEAD && \
- (x)->Blink == LIST_HEAD) || \
- ((x)->Total != 0 && \
- (x)->Flink != LIST_HEAD && \
- (x)->Blink != LIST_HEAD)); \
+ (x)->Blink == LIST_HEAD) || \
+ ((x)->Total != 0 && \
+ (x)->Flink != LIST_HEAD && \
+ (x)->Blink != LIST_HEAD)); \
} while (0)
#else
#define ASSERT_LIST_INVARIANT(x)
}
/* We are not on a list anymore */
- ASSERT_LIST_INVARIANT(ListHead);
+ ASSERT_LIST_INVARIANT(ListHead);
Pfn1->u1.Flink = Pfn1->u2.Blink = 0;
/* Zero flags but restore color and cache */
VOID
NTAPI
MiProtectFreeNonPagedPool(IN PVOID VirtualAddress,
- IN ULONG PageCount)
+ IN ULONG PageCount)
{
PMMPTE PointerPte, LastPte;
MMPTE TempPte;
BOOLEAN
NTAPI
MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress,
- IN ULONG PageCount)
+ IN ULONG PageCount)
{
PMMPTE PointerPte;
MMPTE TempPte;
MmAllocateMappingAddress(IN SIZE_T NumberOfBytes,
IN ULONG PoolTag)
{
- UNIMPLEMENTED;
- return NULL;
+ UNIMPLEMENTED;
+ return NULL;
}
/*
MmFreeMappingAddress(IN PVOID BaseAddress,
IN ULONG PoolTag)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
}
/* EOF */
/* Copy the procedure name */
RtlStringCbCopyA(*MissingApi,
MAXIMUM_FILENAME_LENGTH,
- (PCHAR)&NameImport->Name[0]);
+ (PCHAR)&NameImport->Name[0]);
/* Setup name tables */
DPRINT("Import name: %s\n", NameImport->Name);
HighVpn = BoundaryAddress >> PAGE_SHIFT;
/* Starting from the root, go down until the right-most child
- * which is just behind the boundary*/
+ * which is just behind the boundary*/
LowestNode = Node = RtlRightChildAvl(&Table->BalancedRoot);
while (((Child = RtlRightChildAvl(Node)) != 0 )
- && (Node->EndingVpn < HighVpn )) Node = Child;
+ && (Node->EndingVpn < HighVpn )) Node = Child;
/* Now loop the Vad nodes */
while (Node)
SWAPENTRY SwapEntry;
NTSTATUS Status;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
+
DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n",
Address, Process->UniqueProcessId);
MmReleasePageOp(PageOp);
return(STATUS_UNSUCCESSFUL);
}
-
+
/*
* Check the reference count to ensure this page can be paged out
*/
PMM_REGION Region;
PMM_PAGEOP PageOp;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
+
/*
* There is a window between taking the page fault and locking the
* address space when another thread could load the page so we check
*/
{
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
+
/*
* If we are switching a previously committed region to reserved then
* free any allocated pages within the region
PageOp = MmGetPageOp(MArea, Process->UniqueProcessId, addr,
NULL, 0, MM_PAGEOP_CHANGEPROTECT, TRUE);
} while(PageOp == NULL);
-
+
/* Should we enable/disable virtual mapping? */
- if((NewProtect & PAGE_NOACCESS) &&
- !(OldProtect & PAGE_NOACCESS) &&
+ if((NewProtect & PAGE_NOACCESS) &&
+ !(OldProtect & PAGE_NOACCESS) &&
(MmIsPagePresent(Process, addr)))
{
/* Set other flags if any */
{
MmEnableVirtualMapping(Process, addr);
}
-
+
/* Set new protection flags */
if(MmIsPagePresent(Process, addr))
{
DPRINT1("Must supply MEM_COMMIT with MEM_LARGE_PAGES\n");
return STATUS_INVALID_PARAMETER_5;
}
-
+
/* These flags are not allowed with large page allocations */
if (AllocationType & (MEM_PHYSICAL | MEM_RESET | MEM_WRITE_WATCH))
{
ProbeForWritePointer(UBaseAddress);
ProbeForWriteUlong(URegionSize);
}
-
+
/* Capture their values */
PBaseAddress = *UBaseAddress;
PRegionSize = *URegionSize;
_SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
-
+
/* Make sure the allocation isn't past the VAD area */
if (PBaseAddress >= MM_HIGHEST_VAD_ADDRESS)
{
DPRINT1("Virtual allocation base above User Space\n");
return STATUS_INVALID_PARAMETER_2;
}
-
+
/* Make sure the allocation wouldn't overflow past the VAD area */
if ((((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) - (ULONG_PTR)PBaseAddress) < PRegionSize)
{
DPRINT1("Region size would overflow into kernel-memory\n");
return STATUS_INVALID_PARAMETER_4;
}
-
+
/* Make sure there's a size specified */
if (!PRegionSize)
{
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Check if not running in the current process */
if (CurrentProcess != Process)
{
Attached = TRUE;
}
}
-
+
/* Check for large page allocations */
if (AllocationType & MEM_LARGE_PAGES)
{
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Check if not running in the current process */
if (CurrentProcess != Process)
{
case MEM_RELEASE:
/* MEM_RELEASE must be used with the exact base and length
* that was returned by NtAllocateVirtualMemory */
-
+
/* Verify the base address is correct */
if (MemoryArea->StartingAddress != BaseAddress)
{
//
return TRUE;
}
-
+
//
// FIXME-USER: Shouldn't get here yet
//
MMPTE TempPte;
NTSTATUS Status;
PFN_NUMBER Pfn;
-
+
//
// Check if this is a user-mode, non-kernel or non-current address
//
//
ASSERT(FALSE);
}
-
+
//
// Get our templates
//
TempPde = MiArmTemplatePde;
TempPte = MiArmTemplatePte;
-
+
//
// Get the PDE
//
// Invalid PDE, is this a kernel address?
//
if (Address >= MmSystemRangeStart)
- {
+ {
//
// Does it exist in the kernel page directory?
//
kernelHack:
DPRINT1("Must create a page for: %p PDE: %p\n", // Offset: %lx!\n",
Address, PointerPde);//, PdeOffset);
-
+
//
// Allocate a non paged pool page for the PDE
//
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
if (!NT_SUCCESS(Status)) return NULL;
-
+
//
// Setup the PFN
//
TempPde.u.Hard.Coarse.PageFrameNumber = (Pfn << PAGE_SHIFT) >> CPT_SHIFT;
-
+
//
// Write the PDE
//
ASSERT(PointerPde->u.Hard.Coarse.Valid == 0);
ASSERT(TempPde.u.Hard.Coarse.Valid == 1);
*PointerPde = TempPde;
-
+
//
// Save it
//
//MmGlobalKernelPageDirectory[PdeOffset] = TempPde.u.Hard.AsUlong;
//DPRINT1("KPD: %p PDEADDR: %p\n", &MmGlobalKernelPageDirectory[PdeOffset], MiGetPdeAddress(Address));
-
+
//
// FIXFIX: Double check with Felix tomorrow
//
//
PointerPte = MiGetPteAddress(MiGetPteAddress(Address));
DPRINT1("PointerPte: %p\n", PointerPte);
-
+
//
// Write the PFN of the PDE
//
TempPte.u.Hard.PageFrameNumber = Pfn;
-
+
//
// Write the PTE
//
*PointerPte = TempPte;
/////
}
-
+
//
// Now set the actual PDE
//
// Is this a create operation? If not, fail
//
if (Create == FALSE) return NULL;
-
+
//
// THIS WHOLE PATH IS TODO
//
goto kernelHack;
ASSERT(FALSE);
-
+
//
// Allocate a non paged pool page for the PDE
//
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
if (!NT_SUCCESS(Status)) return NULL;
-
+
//
// Make the entry valid
//
TempPde.u.Hard.AsUlong = 0xDEADBEEF;
-
+
//
// Set it
//
*PointerPde = TempPde;
}
}
-
+
//
// Return the PTE
//
PMMPTE PointerPte;
MMPTE Pte;
Pte.u.Hard.AsUlong = 0;
-
+
//
// Get the PTE
//
IN PVOID Address)
{
PMMPDE_HARDWARE PointerPde;
-
+
//
// Not valid for kernel addresses
//
DPRINT("MmDeletePageTable(%p, %p)\n", Process, Address);
ASSERT(Address < MmSystemRangeStart);
-
+
//
// Check if this is for a different process
//
//
ASSERT(FALSE);
}
-
+
//
// Get the PDE
//
PointerPde = MiGetPdeAddress(Address);
-
+
//
// On ARM, we use a section mapping for the original low-memory mapping
//
//
ASSERT(PointerPde->u.Hard.Coarse.Valid == 1);
}
-
+
//
// Clear the PDE
//
PointerPde->u.Hard.AsUlong = 0;
ASSERT(PointerPde->u.Hard.Coarse.Valid == 0);
-
+
//
// Invalidate the TLB entry
//
PMMPDE_HARDWARE PageDirectory, PointerPde;
MMPDE_HARDWARE TempPde;
ASSERT(FALSE);
-
+
//
// Loop two tables (Hyperspace and TTB). Each one is 16KB
//
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
if (!NT_SUCCESS(Status)) ASSERT(FALSE);
}
-
+
//
// Map the base
//
PageDirectory = MmCreateHyperspaceMapping(Pfn[0]);
-
+
//
// Copy the PDEs for kernel-mode
//
RtlCopyMemory(PageDirectory + MiGetPdeOffset(MmSystemRangeStart),
MmGlobalKernelPageDirectory + MiGetPdeOffset(MmSystemRangeStart),
(1024 - MiGetPdeOffset(MmSystemRangeStart)) * sizeof(ULONG));
-
-
+
+
//
// Setup the PDE for the table base
//
TempPde = MiArmTemplatePde;
TempPde.u.Hard.Coarse.PageFrameNumber = (Pfn[0] << PAGE_SHIFT) >> CPT_SHIFT;
PointerPde = &PageDirectory[MiGetPdeOffset(PTE_BASE)];
-
+
//
// Write the PDE
//
ASSERT(PointerPde->u.Hard.Coarse.Valid == 0);
ASSERT(TempPde.u.Hard.Coarse.Valid == 1);
*PointerPde = TempPde;
-
+
//
// Setup the PDE for the hyperspace
//
TempPde.u.Hard.Coarse.PageFrameNumber = (Pfn[1] << PAGE_SHIFT) >> CPT_SHIFT;
PointerPde = &PageDirectory[MiGetPdeOffset(HYPER_SPACE)];
-
+
//
// Write the PDE
//
// Unmap the page directory
//
MmDeleteHyperspaceMapping(PageDirectory);
-
+
//
// Return the page table base
//
ULONG OldPdeOffset, PdeOffset, i;
DPRINT("[KMAP]: %p %d\n", Address, PageCount);
//ASSERT(Address >= MmSystemRangeStart);
-
+
//
// Get our template PTE
//
TempPte = MiArmTemplatePte;
-
+
//
// Loop every page
//
// Get rid of the old L2 Table, if this was the last PTE on it
//
MiUnmapPageTable(PointerPte);
-
+
//
// Get the PTE for this address, and create the PDE for it
//
ASSERT(PointerPte);
PointerPte++;
}
-
+
//
// Save the current PDE
//
OldPdeOffset = PdeOffset;
-
+
//
// Set the PFN
//
TempPte.u.Hard.PageFrameNumber = *Pages++;
-
+
//
// Write the PTE
//
ASSERT(PointerPte->u.Hard.Valid == 0);
ASSERT(TempPte.u.Hard.Valid == 1);
*PointerPte = TempPte;
-
+
//
// Move to the next page
//
Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE);
}
-
+
//
// All done
//
PageCount,
TRUE);
}
-
+
//
// FIXME-USER: Support user-mode mappings
//
IN ULONG PageCount)
{
ULONG i;
-
+
//
// Loop each page
//
//
ASSERT(MmIsPageInUse(Pages[i]));
}
-
+
//
// Call the unsafe version
//
MmRawDeleteVirtualMapping(IN PVOID Address)
{
PMMPTE PointerPte;
-
+
//
// Get the PTE
//
// Destroy it
//
PointerPte->u.Hard.AsUlong = 0;
-
+
//
// Flush the TLB
//
PMMPTE PointerPte;
MMPTE Pte;
PFN_NUMBER Pfn = 0;
-
+
//
// Get the PTE
//
PointerPte = MiGetPageTableForProcess(NULL, Address, FALSE);
if (PointerPte)
- {
+ {
//
// Save and destroy the PTE
//
Pte = *PointerPte;
PointerPte->u.Hard.AsUlong = 0;
-
+
//
// Flush the TLB
//
MiFlushTlb(PointerPte, Address);
-
+
//
// Unmap the PFN
//
Pfn = Pte.u.Hard.PageFrameNumber;
-
+
//
// Release the PFN if it was ours
//
if ((FreePage) && (Pfn)) MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
}
-
+
//
// Return if the page was dirty
//
IN PVOID Address)
{
MMPTE Pte;
-
+
//
// Get the PTE
//
Pte = MiGetPageEntryForProcess(Process, Address);
if (Pte.u.Hard.Valid == 0) return 0;
-
+
//
// Return PFN
//
IN PVOID Address)
{
MMPTE Pte;
-
+
//
// Get the PTE
//
Pte = MiGetPageEntryForProcess(Process, Address);
-
+
//
// Make sure it exists, but is faulting
//
{
ULONG i;
PULONG CurrentPageDirectory = (PULONG)PDE_BASE;
-
+
//
// Good place to setup template PTE/PDEs.
// We are lazy and pick a known-good PTE
//
MiArmTemplatePte = *MiGetPteAddress(0x80000000);
MiArmTemplatePde = *MiGetPdeAddress(0x80000000);
-
+
//
// Loop the 2GB of address space which belong to the kernel
//
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PVOID BaseAddress;
NTSTATUS Status;
-
+
//
// Create memory area for the PTE area
//
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
-
+
//
// Create memory area for the PDE area
//
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
-
+
//
// And finally, hyperspace
//
PhysicalAddress.LowPart += BYTE_OFFSET(Address);
return PhysicalAddress;
}
-
+
//
// Get the PTE
//
//
PhysicalAddress.QuadPart = 0;
}
-
+
//
// Return the physical address
//
MiInitializeUserPfnBitmap(VOID)
{
PVOID Bitmap;
-
+
/* Allocate enough buffer for the PFN bitmap and align it on 32-bits */
Bitmap = ExAllocatePoolWithTag(NonPagedPool,
(((MmHighestPhysicalPage + 1) + 31) / 32) * 4,
{
ULONG Position;
KIRQL OldIrql;
-
+
/* Find the first user page */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Position = RtlFindSetBits(&MiUserPfnBitMap, 1, 0);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
if (Position == 0xFFFFFFFF) return 0;
-
+
/* Return it */
ASSERT(Position != 0);
ASSERT_IS_ROS_PFN(MiGetPfnEntry(Position));
{
ULONG Position;
KIRQL OldIrql;
-
+
/* Find the next user page */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Position = RtlFindSetBits(&MiUserPfnBitMap, 1, (ULONG)PreviousPfn + 1);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
if (Position == 0xFFFFFFFF) return 0;
-
+
/* Return it */
ASSERT(Position != 0);
ASSERT_IS_ROS_PFN(MiGetPfnEntry(Position));
PPHYSICAL_PAGE Pfn1;
INT LookForZeroedPages;
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-
+
//
// Convert the low address into a PFN
//
LowPage = (PFN_NUMBER)(LowAddress.QuadPart >> PAGE_SHIFT);
-
+
//
// Convert, and normalize, the high address into a PFN
//
HighPage = (PFN_NUMBER)(HighAddress.QuadPart >> PAGE_SHIFT);
if (HighPage > MmHighestPhysicalPage) HighPage = MmHighestPhysicalPage;
-
+
//
// Validate skipbytes and convert them into pages
//
if (BYTE_OFFSET(SkipBytes.LowPart)) return NULL;
SkipPages = (PFN_NUMBER)(SkipBytes.QuadPart >> PAGE_SHIFT);
-
+
/* This isn't supported at all */
if (SkipPages) DPRINT1("WARNING: Caller requesting SkipBytes, MDL might be mismatched\n");
//
Mdl = MmCreateMdl(NULL, NULL, PageCount << PAGE_SHIFT);
if (Mdl) break;
-
+
//
// This function is not required to return the amount of pages requested
// In fact, it can return as little as 1 page, and callers are supposed
//
PageCount -= (PageCount >> 4);
} while (PageCount);
-
+
//
// Wow, not even a single page was around!
//
if (!Mdl) return NULL;
-
+
//
// This is where the page array starts....
//
MdlPage = (PPFN_NUMBER)(Mdl + 1);
-
+
//
// Lock the PFN database
//
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-
+
//
// Are we looking for any pages, without discriminating?
//
ASSERT(PagesFound);
break;
}
-
+
/* Grab the page entry for it */
Pfn1 = MiGetPfnEntry(Page);
-
+
//
// Make sure it's really free
//
ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
-
+
/* Now setup the page and mark it */
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u2.ShareCount = 1;
Pfn1->u3.e1.StartOfAllocation = 1;
Pfn1->u3.e1.EndOfAllocation = 1;
Pfn1->u4.VerifierAllocation = 0;
-
+
//
// Save it into the MDL
//
//
Pfn1 = MiGetPfnEntry(Page);
ASSERT(Pfn1);
-
+
//
// Make sure it's free and if this is our first pass, zeroed
//
if (MiIsPfnInUse(Pfn1)) continue;
if ((Pfn1->u3.e1.PageLocation == ZeroedPageList) != LookForZeroedPages) continue;
-
+
/* Remove the page from the free or zero list */
ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
MI_SET_USAGE(MI_USAGE_MDL);
MI_SET_PROCESS2("Kernel");
MiUnlinkFreeOrZeroedPage(Pfn1);
-
+
//
// Sanity checks
//
ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
-
+
//
// Now setup the page and mark it
//
*MdlPage++ = Page;
if (++PagesFound == PageCount) break;
}
-
+
//
// If the first pass was enough, don't keep going, otherwise, go again
//
if (PagesFound == PageCount) break;
}
}
-
+
//
// Now release the PFN count
//
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
-
+
//
// We might've found less pages, but not more ;-)
//
ExFreePool(Mdl);
return NULL;
}
-
+
//
// Write out how many pages we found
//
Mdl->ByteCount = (ULONG)(PagesFound << PAGE_SHIFT);
-
+
//
// Terminate the MDL array if there's certain missing pages
//
if (PagesFound != PageCount) *MdlPage = LIST_HEAD;
-
+
//
// Now go back and loop over all the MDL pages
//
//
Page = *MdlPage++;
if (Page == LIST_HEAD) break;
-
+
//
// Get the PFN entry for the page and check if we should zero it out
//
if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPhysicalPage(Page);
Pfn1->u3.e1.PageLocation = ActiveAndValid;
}
-
+
//
// We're done, mark the pages as locked
//
{
KIRQL oldIrql;
PMMPFN Pfn1;
-
+
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
{
/* Should not be trying to insert an RMAP for a non-active page */
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
-
+
/* Set the list head address */
MI_GET_ROS_DATA(Pfn1)->RmapListHead = ListHead;
}
{
/* ReactOS semantics dictate the page is STILL active right now */
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
-
+
/* In this case, the RMAP is actually being removed, so clear field */
MI_GET_ROS_DATA(Pfn1)->RmapListHead = NULL;
/* ReactOS semantics will now release the page, which will make it free and enter a colored list */
}
-
+
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
-
+
/* Get the list head */
ListHead = MI_GET_ROS_DATA(Pfn1)->RmapListHead;
-
+
/* Should not have an RMAP for a non-active page */
ASSERT(MiIsPfnInUse(Pfn1) == TRUE);
-
+
/* Release PFN database and return rmap list head */
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return ListHead;
{
KIRQL oldIrql;
PPHYSICAL_PAGE Page;
-
+
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
ASSERT_IS_ROS_PFN(Page);
-
+
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MI_GET_ROS_DATA(Page)->SwapEntry = SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
SWAPENTRY SwapEntry;
KIRQL oldIrql;
PPHYSICAL_PAGE Page;
-
+
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
ASSERT_IS_ROS_PFN(Page);
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
ASSERT_IS_ROS_PFN(Page);
-
+
Page->u3.e2.ReferenceCount++;
}
Page = MiGetPfnEntry(Pfn);
ASSERT(Page);
ASSERT_IS_ROS_PFN(Page);
-
+
Page->u3.e2.ReferenceCount--;
if (Page->u3.e2.ReferenceCount == 0)
{
/* Mark the page temporarily as valid, we're going to make it free soon */
Page->u3.e1.PageLocation = ActiveAndValid;
-
+
/* It's not a ROS PFN anymore */
Page->u4.AweAllocation = FALSE;
ExFreePool(MI_GET_ROS_DATA(Page));
{
PFN_NUMBER PfnOffset;
PMMPFN Pfn1;
-
+
PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
if (!PfnOffset)
Pfn1 = MiGetPfnEntry(PfnOffset);
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
-
+
/* This marks the PFN as a ReactOS PFN */
Pfn1->u4.AweAllocation = TRUE;
-
+
/* Allocate the extra ReactOS Data and zero it out */
Pfn1->RosMmData = (LONG)ExAllocatePoolWithTag(NonPagedPool, sizeof(MMROSPFN), 'RsPf');
ASSERT(MI_GET_ROS_DATA(Pfn1) != NULL);
ASSERT_IS_ROS_PFN(Pfn1);
MI_GET_ROS_DATA(Pfn1)->SwapEntry = 0;
MI_GET_ROS_DATA(Pfn1)->RmapListHead = NULL;
-
+
return PfnOffset;
}
#define PA_BIT_CD (4)
#define PA_BIT_ACCESSED (5)
#define PA_BIT_DIRTY (6)
-#define PA_BIT_GLOBAL (8)
+#define PA_BIT_GLOBAL (8)
#define PA_PRESENT (1 << PA_BIT_PRESENT)
#define PA_READWRITE (1 << PA_BIT_READWRITE)
#define PA_ACCESSED (1 << PA_BIT_ACCESSED)
#define PA_GLOBAL (1 << PA_BIT_GLOBAL)
-#define HYPERSPACE (0xc0400000)
-#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
+#define HYPERSPACE (0xc0400000)
+#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
ULONG MmGlobalKernelPageDirectory[1024];
ProtectToPTE(ULONG flProtect)
{
ULONG Attributes = 0;
-
+
if (flProtect & (PAGE_NOACCESS|PAGE_GUARD))
{
Attributes = 0;
DPRINT1("Unknown main protection type.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
if (flProtect & PAGE_SYSTEM)
{
}
PFN_NUMBER Pfn;
ULONG Entry;
PULONG Pt, PageDir;
-
+
if (Address < MmSystemRangeStart)
{
/* We should have a process for user land addresses */
}
return (PULONG)MiAddressToPte(Address);
}
-
+
/* This is for kernel land address */
PageDir = (PULONG)MiAddressToPde(Address);
if (0 == InterlockedCompareExchangePte(PageDir, 0, 0))
{
return TRUE;
}
-
+
if (Pt)
{
MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(Pt));
{
ULONG Pte;
PULONG Pt;
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
if (Pt)
{
BOOLEAN WasValid;
ULONG Pte;
PULONG Pt;
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
if (Pt == NULL)
{
{
Pte = *Pt;
} while (Pte != InterlockedCompareExchangePte(Pt, Pte & ~PA_PRESENT, Pte));
-
+
if(Pte & PA_PRESENT)
MiFlushTlb(Pt, Address);
else
MmUnmapPageTable(Pt);
-
+
WasValid = (PAGE_MASK(Pte) != 0);
if (!WasValid)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
/*
* Return some information to the caller
*/
MmRawDeleteVirtualMapping(PVOID Address)
{
PULONG Pt;
-
+
Pt = MmGetPageTableForProcess(NULL, Address, FALSE);
if (Pt && *Pt)
{
PFN_NUMBER Pfn;
ULONG Pte;
PULONG Pt;
-
+
DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
Process, Address, FreePage, WasDirty, Page);
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
-
+
if (Pt == NULL)
{
if (WasDirty != NULL)
}
return;
}
-
+
/*
* Atomically set the entry to zero and get the old value.
*/
Pte = InterlockedExchangePte(Pt, 0);
-
-
+
+
WasValid = (PAGE_MASK(Pte) != 0);
if (WasValid)
{
Pfn = 0;
MmUnmapPageTable(Pt);
}
-
+
if (FreePage && WasValid)
{
MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
}
-
+
/*
* Return some information to the caller
*/
VOID
NTAPI
MmGetPageFileMapping(PEPROCESS Process, PVOID Address,
- SWAPENTRY* SwapEntry)
+ SWAPENTRY* SwapEntry)
/*
* FUNCTION: Get a page file mapping
*/
{
- ULONG Entry = MmGetPageEntryForProcess(Process, Address);
- *SwapEntry = Entry >> 1;
+ ULONG Entry = MmGetPageEntryForProcess(Process, Address);
+ *SwapEntry = Entry >> 1;
}
VOID
{
ULONG Pte;
PULONG Pt;
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
-
+
if (Pt == NULL)
{
*SwapEntry = 0;
return;
}
-
+
/*
* Atomically set the entry to zero and get the old value.
*/
Pte = InterlockedExchangePte(Pt, 0);
-
+
//MiFlushTlb(Pt, Address);
MmUnmapPageTable(Pt);
-
+
if(!(Pte & 0x800))
{
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
/*
* Return some information to the caller
*/
{
PULONG Pt;
ULONG Pte;
-
+
if (Address < MmSystemRangeStart && Process == NULL)
{
DPRINT1("MmSetCleanPage is called for user space without a process.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
-
+
if (Pt == NULL)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
do
{
Pte = *Pt;
} while (Pte != InterlockedCompareExchangePte(Pt, Pte & ~PA_DIRTY, Pte));
-
+
if (Pte & PA_DIRTY)
{
MiFlushTlb(Pt, Address);
{
PULONG Pt;
ULONG Pte;
-
+
if (Address < MmSystemRangeStart && Process == NULL)
{
DPRINT1("MmSetDirtyPage is called for user space without a process.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
if (Pt == NULL)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
do
{
Pte = *Pt;
{
PULONG Pt;
ULONG Pte;
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
if (Pt == NULL)
{
//KeBugCheck(MEMORY_MANAGEMENT);
return;
}
-
+
/* Do not mark a 0 page as present */
if(0 == InterlockedCompareExchangePte(Pt, 0, 0))
return;
-
+
do
{
Pte = *Pt;
{
PULONG Pt;
ULONG Pte;
-
+
if (Process == NULL && Address < MmSystemRangeStart)
{
DPRINT1("No process\n");
{
KeBugCheck(MEMORY_MANAGEMENT);
}
-
+
Pt = MmGetPageTableForProcess(Process, Address, TRUE);
if (Pt == NULL)
{
}
//MiFlushTlb(Pt, Address);
MmUnmapPageTable(Pt);
-
+
return(STATUS_SUCCESS);
}
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)
KeBugCheck(MEMORY_MANAGEMENT);
}
}
-
+
Attributes = ProtectToPTE(flProtect);
Attributes &= 0xfff;
if (Address >= MmSystemRangeStart)
{
Attributes |= PA_USER;
}
-
+
Addr = Address;
/* MmGetPageTableForProcess should be called on the first run, so
* let this trigger it */
Pt++;
}
oldPdeOffset = PdeOffset;
-
+
Pte = InterlockedExchangePte(Pt, PFN_TO_PTE(Pages[i]) | Attributes);;
/* There should not be anything valid here */
if (PAGE_MASK(Pte) != 0)
KeBugCheck(MEMORY_MANAGEMENT);
}
/* flush if currently mapped, just continue editing if hyperspace
- * NOTE : This check is similar to what is done in MiFlushTlb, but we
+ * NOTE : This check is similar to what is done in MiFlushTlb, but we
* don't use it because it would unmap the page table */
if (Addr >= MmSystemRangeStart || (!IS_HYPERSPACE(Pt)))
{
KeInvalidateTlbEntry(Addr);
}
}
-
+
ASSERT(Addr > Address);
MmUnmapPageTable(Pt);
-
+
return(STATUS_SUCCESS);
}
ULONG PageCount)
{
ULONG i;
-
+
for (i = 0; i < PageCount; i++)
{
if (!MmIsPageInUse(Pages[i]))
KeBugCheck(MEMORY_MANAGEMENT);
}
}
-
+
return(MmCreateVirtualMappingUnsafe(Process,
Address,
flProtect,
{
ULONG Entry;
ULONG Protect;
-
+
Entry = MmGetPageEntryForProcess(Process, Address);
-
-
+
+
if (!(Entry & PA_PRESENT))
{
Protect = PAGE_NOACCESS;
{
Protect |= PAGE_SYSTEM;
}
-
+
}
return(Protect);
}
ULONG Attributes = 0;
PULONG Pt;
ULONG Pte;
-
+
DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
Process, Address, flProtect);
-
+
Attributes = ProtectToPTE(flProtect);
Attributes &= 0xfff;
{
Attributes |= PA_USER;
}
-
+
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
if (Pt == NULL)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
Pte = InterlockedExchangePte(Pt, PAGE_MASK(*Pt) | Attributes | (*Pt & (PA_ACCESSED|PA_DIRTY)));
-
+
if(!PAGE_MASK(Pte))
{
DPRINT1("Invalid Pte %lx\n", Pte);
{
PHYSICAL_ADDRESS p;
ULONG Pte;
-
+
DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
Pte = MmGetPageEntryForProcess(NULL, vaddr);
if (Pte != 0 && Pte & PA_PRESENT)
{
ULONG i;
PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
-
+
DPRINT("MmInitGlobalKernelPageDirectory()\n");
-
+
for (i = ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 1024; i++)
{
if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) &&
#define PA_BIT_CD (4)
#define PA_BIT_ACCESSED (5)
#define PA_BIT_DIRTY (6)
-#define PA_BIT_GLOBAL (8)
+#define PA_BIT_GLOBAL (8)
#define PA_PRESENT (1 << PA_BIT_PRESENT)
#define PA_READWRITE (1 << PA_BIT_READWRITE)
#define PA_ACCESSED (1 << PA_BIT_ACCESSED)
#define PA_GLOBAL (1 << PA_BIT_GLOBAL)
-#define PAGETABLE_MAP (0xc0000000)
-#define PAGEDIRECTORY_MAP (0xc0000000 + (PAGETABLE_MAP / (1024)))
+#define PAGETABLE_MAP (0xc0000000)
+#define PAGEDIRECTORY_MAP (0xc0000000 + (PAGETABLE_MAP / (1024)))
-#define PAE_PAGEDIRECTORY_MAP (0xc0000000 + (PAGETABLE_MAP / (512)))
+#define PAE_PAGEDIRECTORY_MAP (0xc0000000 + (PAGETABLE_MAP / (512)))
-#define HYPERSPACE (Ke386Pae ? 0xc0800000 : 0xc0400000)
-#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
+#define HYPERSPACE (Ke386Pae ? 0xc0800000 : 0xc0400000)
+#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
ULONG MmGlobalKernelPageDirectory[1024];
ULONGLONG MmGlobalKernelPageDirectoryForPAE[2048];
#define PAE_ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (512 * PAGE_SIZE))
-#define PAE_ADDR_TO_PDE(v) (PULONGLONG) (PAE_PAGEDIRECTORY_MAP + \
+#define PAE_ADDR_TO_PDE(v) (PULONGLONG) (PAE_PAGEDIRECTORY_MAP + \
((((ULONG_PTR)(v)) / (512 * 512))&(~0x7)))
-#define PAE_ADDR_TO_PTE(v) (PULONGLONG) (PAGETABLE_MAP + ((((ULONG_PTR)(v) / 512))&(~0x7)))
+#define PAE_ADDR_TO_PTE(v) (PULONGLONG) (PAGETABLE_MAP + ((((ULONG_PTR)(v) / 512))&(~0x7)))
#define PAE_ADDR_TO_PDTE_OFFSET(v) (((ULONG_PTR)(v)) / (512 * 512 * PAGE_SIZE))
{
PageDir = (PULONGLONG)MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(PageDirTable[i]));
if (i < PAE_ADDR_TO_PDTE_OFFSET(MmSystemRangeStart))
- {
- for (j = 0; j < 512; j++)
- {
- if (PageDir[j] != 0LL)
- {
+ {
+ for (j = 0; j < 512; j++)
+ {
+ if (PageDir[j] != 0LL)
+ {
DPRINT1("ProcessId %d, Pde for %08x - %08x is not freed, RefCount %d\n",
- Process->UniqueProcessId,
- (i * 512 + j) * 512 * PAGE_SIZE, (i * 512 + j + 1) * 512 * PAGE_SIZE - 1,
- ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable[i*512 + j]);
+ Process->UniqueProcessId,
+ (i * 512 + j) * 512 * PAGE_SIZE, (i * 512 + j + 1) * 512 * PAGE_SIZE - 1,
+ ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable[i*512 + j]);
Pde = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(PageDir[j]));
- for (k = 0; k < 512; k++)
- {
- if(Pde[k] != 0)
- {
- if (Pde[k] & PA_PRESENT)
- {
- DPRINT1("Page at %08x is not freed\n",
- (i * 512 + j) * 512 * PAGE_SIZE + k * PAGE_SIZE);
- }
- else
- {
- DPRINT1("Swapentry %x at %x is not freed\n",
- (i * 512 + j) * 512 * PAGE_SIZE + k * PAGE_SIZE);
- }
- }
- }
- MmDeleteHyperspaceMapping(Pde);
- MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[j]));
- }
- }
- }
- if (i == PAE_ADDR_TO_PDTE_OFFSET(HYPERSPACE))
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)]));
- MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)+1]));
- }
- MmDeleteHyperspaceMapping(PageDir);
+ for (k = 0; k < 512; k++)
+ {
+ if(Pde[k] != 0)
+ {
+ if (Pde[k] & PA_PRESENT)
+ {
+ DPRINT1("Page at %08x is not freed\n",
+ (i * 512 + j) * 512 * PAGE_SIZE + k * PAGE_SIZE);
+ }
+ else
+ {
+ DPRINT1("Swapentry %x at %x is not freed\n",
+ (i * 512 + j) * 512 * PAGE_SIZE + k * PAGE_SIZE);
+ }
+ }
+ }
+ MmDeleteHyperspaceMapping(Pde);
+ MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[j]));
+ }
+ }
+ }
+ if (i == PAE_ADDR_TO_PDTE_OFFSET(HYPERSPACE))
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)]));
+ MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)+1]));
+ }
+ MmDeleteHyperspaceMapping(PageDir);
MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDirTable[i]));
}
MmDeleteHyperspaceMapping((PVOID)PageDirTable);
if (PageDir[i] != 0)
{
DPRINT1("Pde for %08x - %08x is not freed, RefCount %d\n",
- i * 4 * 1024 * 1024, (i + 1) * 4 * 1024 * 1024 - 1,
- ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable[i]);
- Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(PageDir[i]));
- for (j = 0; j < 1024; j++)
- {
- if(Pde[j] != 0)
- {
- if (Pde[j] & PA_PRESENT)
- {
- DPRINT1("Page at %08x is not freed\n",
- i * 4 * 1024 * 1024 + j * PAGE_SIZE);
- }
- else
- {
- DPRINT1("Swapentry %x at %x is not freed\n",
- Pde[j], i * 4 * 1024 * 1024 + j * PAGE_SIZE);
- }
- }
- }
- MmDeleteHyperspaceMapping(Pde);
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[i]));
- }
+ i * 4 * 1024 * 1024, (i + 1) * 4 * 1024 * 1024 - 1,
+ ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable[i]);
+ Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(PageDir[i]));
+ for (j = 0; j < 1024; j++)
+ {
+ if(Pde[j] != 0)
+ {
+ if (Pde[j] & PA_PRESENT)
+ {
+ DPRINT1("Page at %08x is not freed\n",
+ i * 4 * 1024 * 1024 + j * PAGE_SIZE);
+ }
+ else
+ {
+ DPRINT1("Swapentry %x at %x is not freed\n",
+ Pde[j], i * 4 * 1024 * 1024 + j * PAGE_SIZE);
+ }
+ }
+ }
+ MmDeleteHyperspaceMapping(Pde);
+ MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[i]));
+ }
}
MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[ADDR_TO_PDE_OFFSET(HYPERSPACE)]));
MmDeleteHyperspaceMapping(PageDir);
{
/* Share the directory base with the idle process */
*DirectoryTableBase = PsGetCurrentProcess()->Pcb.DirectoryTableBase;
-
+
/* Initialize the Addresss Space */
MmInitializeAddressSpace(Process, (PMADDRESS_SPACE)&Process->VadRoot);
-
+
/* The process now has an address space */
Process->HasAddressSpace = TRUE;
return STATUS_SUCCESS;
{
MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
}
-
+
return FALSE;
}
}
PageDirTable = MmCreateHyperspaceMapping(Pfn[0]);
for (i = 0; i < 4; i++)
{
- PageDirTable[i] = PAE_PFN_TO_PTE(Pfn[1+i]) | PA_PRESENT;
+ PageDirTable[i] = PAE_PFN_TO_PTE(Pfn[1+i]) | PA_PRESENT;
}
MmDeleteHyperspaceMapping(PageDirTable);
for (i = PAE_ADDR_TO_PDTE_OFFSET(MmSystemRangeStart); i < 4; i++)
{
PageDir = (PULONGLONG)MmCreateHyperspaceMapping(Pfn[i+1]);
memcpy(PageDir, &MmGlobalKernelPageDirectoryForPAE[i * 512], 512 * sizeof(ULONGLONG));
- if (PAE_ADDR_TO_PDTE_OFFSET(PAGETABLE_MAP) == i)
- {
+ if (PAE_ADDR_TO_PDTE_OFFSET(PAGETABLE_MAP) == i)
+ {
for (j = 0; j < 4; j++)
{
PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(PAGETABLE_MAP) + j] = PAE_PFN_TO_PTE(Pfn[1+j]) | PA_PRESENT | PA_READWRITE;
}
- }
- if (PAE_ADDR_TO_PDTE_OFFSET(HYPERSPACE) == i)
- {
- PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)] = PAE_PFN_TO_PTE(Pfn[5]) | PA_PRESENT | PA_READWRITE;
- PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)+1] = PAE_PFN_TO_PTE(Pfn[6]) | PA_PRESENT | PA_READWRITE;
- }
+ }
+ if (PAE_ADDR_TO_PDTE_OFFSET(HYPERSPACE) == i)
+ {
+ PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)] = PAE_PFN_TO_PTE(Pfn[5]) | PA_PRESENT | PA_READWRITE;
+ PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)+1] = PAE_PFN_TO_PTE(Pfn[6]) | PA_PRESENT | PA_READWRITE;
+ }
MmDeleteHyperspaceMapping(PageDir);
}
}
if (Entry == 0LL)
{
if (Create == FALSE)
- {
- MmDeleteHyperspaceMapping(PageDir);
- return NULL;
- }
+ {
+ MmDeleteHyperspaceMapping(PageDir);
+ return NULL;
+ }
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
- if (!NT_SUCCESS(Status))
- {
- ASSERT(FALSE);
- }
+ if (!NT_SUCCESS(Status))
+ {
+ ASSERT(FALSE);
+ }
Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER;
- Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
- if (Entry != 0LL)
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
- Pfn = PAE_PTE_TO_PFN(Entry);
- }
+ Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
+ if (Entry != 0LL)
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ Pfn = PAE_PTE_TO_PFN(Entry);
+ }
}
else
{
{
if (Address >= MmSystemRangeStart)
{
- if (MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)] == 0LL)
- {
- if (Create == FALSE)
- {
+ if (MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)] == 0LL)
+ {
+ if (Create == FALSE)
+ {
return NULL;
- }
+ }
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
- if (!NT_SUCCESS(Status))
- {
- ASSERT(FALSE);
- }
- Entry = PAE_PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
+ if (!NT_SUCCESS(Status))
+ {
+ ASSERT(FALSE);
+ }
+ Entry = PAE_PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
if (Ke386GlobalPagesEnabled)
- {
- Entry |= PA_GLOBAL;
- }
- if (0LL != ExfInterlockedCompareExchange64UL(&MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &Entry, &ZeroEntry))
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
- }
- }
- (void)ExfInterlockedCompareExchange64UL(PageDir, &MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &ZeroEntry);
+ {
+ Entry |= PA_GLOBAL;
+ }
+ if (0LL != ExfInterlockedCompareExchange64UL(&MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &Entry, &ZeroEntry))
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ }
+ }
+ (void)ExfInterlockedCompareExchange64UL(PageDir, &MmGlobalKernelPageDirectoryForPAE[PAE_ADDR_TO_PDE_OFFSET(Address)], &ZeroEntry);
}
else
{
- if (Create == FALSE)
- {
+ if (Create == FALSE)
+ {
return NULL;
- }
+ }
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
- if (!NT_SUCCESS(Status))
- {
- ASSERT(FALSE);
- }
- Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER;
+ if (!NT_SUCCESS(Status))
+ {
+ ASSERT(FALSE);
+ }
+ Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER;
Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
- if (Entry != 0LL)
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
- }
+ if (Entry != 0LL)
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ }
}
}
return (PULONGLONG)PAE_ADDR_TO_PTE(Address);
if (0 == InterlockedCompareExchangeUL(&PageDir[PdeOffset], 0, 0))
{
if (Create == FALSE)
- {
- MmDeleteHyperspaceMapping(PageDir);
- return NULL;
- }
+ {
+ MmDeleteHyperspaceMapping(PageDir);
+ return NULL;
+ }
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
- if (!NT_SUCCESS(Status) || Pfn == 0)
- {
- ASSERT(FALSE);
- }
+ if (!NT_SUCCESS(Status) || Pfn == 0)
+ {
+ ASSERT(FALSE);
+ }
Entry = InterlockedCompareExchangeUL(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
- if (Entry != 0)
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
- Pfn = PTE_TO_PFN(Entry);
- }
+ if (Entry != 0)
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ Pfn = PTE_TO_PFN(Entry);
+ }
}
else
{
if (Address >= MmSystemRangeStart)
{
if (0 == InterlockedCompareExchangeUL(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0))
- {
- if (Create == FALSE)
- {
+ {
+ if (Create == FALSE)
+ {
return NULL;
- }
+ }
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
- if (!NT_SUCCESS(Status) || Pfn == 0)
- {
- ASSERT(FALSE);
- }
- Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
+ if (!NT_SUCCESS(Status) || Pfn == 0)
+ {
+ ASSERT(FALSE);
+ }
+ Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
if (Ke386GlobalPagesEnabled)
- {
- Entry |= PA_GLOBAL;
- }
- if(0 != InterlockedCompareExchangeUL(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0))
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
- }
- }
+ {
+ Entry |= PA_GLOBAL;
+ }
+ if(0 != InterlockedCompareExchangeUL(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0))
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ }
+ }
(void)InterlockedExchangeUL(PageDir, MmGlobalKernelPageDirectory[PdeOffset]);
}
else
{
- if (Create == FALSE)
- {
+ if (Create == FALSE)
+ {
return NULL;
- }
+ }
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
- if (!NT_SUCCESS(Status) || Pfn == 0)
- {
- ASSERT(FALSE);
- }
+ if (!NT_SUCCESS(Status) || Pfn == 0)
+ {
+ ASSERT(FALSE);
+ }
Entry = InterlockedCompareExchangeUL(PageDir, PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
- if (Entry != 0)
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
- }
+ if (Entry != 0)
+ {
+ MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ }
}
}
return (PULONG)ADDR_TO_PTE(Address);
*/
do
{
- Pte = *Pt;
- tmpPte = Pte & ~PA_PRESENT;
+ Pte = *Pt;
+ tmpPte = Pte & ~PA_PRESENT;
} while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
MiFlushTlb((PULONG)Pt, Address);
*/
if (WasDirty != NULL)
{
- *WasDirty = Pte & PA_DIRTY ? TRUE : FALSE;
+ *WasDirty = Pte & PA_DIRTY ? TRUE : FALSE;
}
if (Page != NULL)
{
/*
* Set the entry to zero
*/
- (void)ExfpInterlockedExchange64UL(Pt, &ZeroPte);
+ (void)ExfpInterlockedExchange64UL(Pt, &ZeroPte);
MiFlushTlb((PULONG)Pt, Address);
}
}
do
{
Pte = *Pt;
- tmpPte = Pte & ~PA_ACCESSED;
+ tmpPte = Pte & ~PA_ACCESSED;
} while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
if (Pte & PA_ACCESSED)
do
{
Pte = *Pt;
- tmpPte = Pte & ~PA_DIRTY;
+ tmpPte = Pte & ~PA_DIRTY;
} while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
if (Pte & PA_DIRTY)
do
{
Pte = *Pt;
- tmpPte = Pte | PA_DIRTY;
+ tmpPte = Pte | PA_DIRTY;
} while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
if (!(Pte & PA_DIRTY))
{
do
{
Pte = *Pt;
- tmpPte = Pte | PA_PRESENT;
+ tmpPte = Pte | PA_PRESENT;
} while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
if (!(Pte & PA_PRESENT))
{
MmCreateVirtualMappingForKernel(PVOID Address,
ULONG flProtect,
PPFN_NUMBER Pages,
- ULONG PageCount)
+ ULONG PageCount)
{
ULONG Attributes;
ULONG i;
if (oldPdeOffset != PdeOffset)
{
Pt = MmGetPageTableForProcessForPAE(NULL, Addr, TRUE);
- if (Pt == NULL)
- {
- ASSERT(FALSE);
- }
+ if (Pt == NULL)
+ {
+ ASSERT(FALSE);
+ }
}
else
{
}
oldPdeOffset = PdeOffset;
- Pte = PFN_TO_PTE(Pages[i]) | Attributes;
- if (NoExecute)
- {
- Pte |= 0x8000000000000000LL;
- }
+ Pte = PFN_TO_PTE(Pages[i]) | Attributes;
+ if (NoExecute)
+ {
+ Pte |= 0x8000000000000000LL;
+ }
Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
if (Pte != 0LL)
{
if (oldPdeOffset != PdeOffset)
{
Pt = MmGetPageTableForProcess(NULL, Addr, TRUE);
- if (Pt == NULL)
- {
- ASSERT(FALSE);
- }
+ if (Pt == NULL)
+ {
+ ASSERT(FALSE);
+ }
}
else
{
ASSERT(FALSE);
}
if (PageCount > 0x10000 ||
- (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
+ (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
{
DPRINT1("Page count to large\n");
- ASSERT(FALSE);
+ ASSERT(FALSE);
}
}
else
ASSERT(FALSE);
}
if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
- (ULONG_PTR) Address / PAGE_SIZE + 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);
+ ASSERT(FALSE);
}
}
Attributes &= ~PA_USER;
if (Ke386GlobalPagesEnabled)
{
- Attributes |= PA_GLOBAL;
+ Attributes |= PA_GLOBAL;
}
}
else
if (oldPdeOffset != PdeOffset)
{
MmUnmapPageTable((PULONG)Pt);
- Pt = MmGetPageTableForProcessForPAE(Process, Addr, TRUE);
- if (Pt == NULL)
- {
- ASSERT(FALSE);
- }
+ Pt = MmGetPageTableForProcessForPAE(Process, Addr, TRUE);
+ if (Pt == NULL)
+ {
+ ASSERT(FALSE);
+ }
}
else
{
oldPdeOffset = PdeOffset;
MmMarkPageMapped(Pages[i]);
- tmpPte = PAE_PFN_TO_PTE(Pages[i]) | Attributes;
- if (NoExecute)
- {
- tmpPte |= 0x8000000000000000LL;
- }
+ 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))
{
MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte)));
}
if (Address < MmSystemRangeStart &&
- ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
+ ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
Attributes & PA_PRESENT)
{
PUSHORT Ptrc;
if (oldPdeOffset != PdeOffset)
{
MmUnmapPageTable(Pt);
- Pt = MmGetPageTableForProcess(Process, Addr, TRUE);
- if (Pt == NULL)
- {
- ASSERT(FALSE);
- }
+ Pt = MmGetPageTableForProcess(Process, Addr, TRUE);
+ if (Pt == NULL)
+ {
+ ASSERT(FALSE);
+ }
}
else
{
{
MmMarkPageUnmapped(PTE_TO_PFN((Pte)));
}
- (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
+ (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
if (Address < MmSystemRangeStart &&
- ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
+ ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
Attributes & PA_PRESENT)
{
PUSHORT Ptrc;
Attributes &= ~PA_USER;
if (Ke386GlobalPagesEnabled)
{
- Attributes |= PA_GLOBAL;
+ Attributes |= PA_GLOBAL;
}
}
else
do
{
Pte = *Pt;
- tmpPte = PAE_PAGE_MASK(Pte) | Attributes | (Pte & (PA_ACCESSED|PA_DIRTY));
- if (NoExecute)
- {
- tmpPte |= 0x8000000000000000LL;
- }
- else
- {
- tmpPte &= ~0x8000000000000000LL;
- }
+ tmpPte = PAE_PAGE_MASK(Pte) | Attributes | (Pte & (PA_ACCESSED|PA_DIRTY));
+ if (NoExecute)
+ {
+ tmpPte |= 0x8000000000000000LL;
+ }
+ else
+ {
+ tmpPte &= ~0x8000000000000000LL;
+ }
} while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
MiFlushTlb((PULONG)Pt, Address);
for (i = Page %1024; i < 1024; i++, Pte++)
{
if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
- {
- break;
- }
+ {
+ break;
+ }
}
if (i >= 1024)
{
Pte = PAE_ADDR_TO_PTE(HYPERSPACE);
- for (i = 0; i < Page % 1024; i++, Pte++)
- {
+ for (i = 0; i < Page % 1024; i++, Pte++)
+ {
if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
- {
- break;
- }
- }
- if (i >= Page % 1024)
- {
- ASSERT(FALSE);
- }
+ {
+ break;
+ }
+ }
+ if (i >= Page % 1024)
+ {
+ ASSERT(FALSE);
+ }
}
}
else
for (i = Page %1024; (LONG)i >= 0; i--, Pte--)
{
if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
- {
- break;
- }
+ {
+ break;
+ }
}
if ((LONG)i < 0)
{
Pte = PAE_ADDR_TO_PTE(HYPERSPACE) + 1023;
- for (i = 1023; i > Page % 1024; i--, Pte--)
- {
+ for (i = 1023; i > Page % 1024; i--, Pte--)
+ {
if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
- {
- break;
- }
- }
- if (i <= Page % 1024)
- {
- ASSERT(FALSE);
- }
+ {
+ break;
+ }
+ }
+ if (i <= Page % 1024)
+ {
+ ASSERT(FALSE);
+ }
}
}
}
for (i = PAE_ADDR_TO_PDTE_OFFSET(Address); i <= PAE_ADDR_TO_PDTE_OFFSET((PVOID)((ULONG_PTR)Address + Size)); i++)
{
if (i == PAE_ADDR_TO_PDTE_OFFSET(Address))
- {
+ {
StartOffset = PAE_ADDR_TO_PDE_PAGE_OFFSET(Address);
- }
- else
- {
- StartOffset = 0;
- }
- if (i == PAE_ADDR_TO_PDTE_OFFSET((PVOID)((ULONG_PTR)Address + Size)))
- {
- EndOffset = PAE_ADDR_TO_PDE_PAGE_OFFSET((PVOID)((ULONG_PTR)Address + Size));
- }
- else
- {
- EndOffset = 511;
- }
+ }
+ else
+ {
+ StartOffset = 0;
+ }
+ if (i == PAE_ADDR_TO_PDTE_OFFSET((PVOID)((ULONG_PTR)Address + Size)))
+ {
+ EndOffset = PAE_ADDR_TO_PDE_PAGE_OFFSET((PVOID)((ULONG_PTR)Address + Size));
+ }
+ else
+ {
+ EndOffset = 511;
+ }
if (Process != NULL && Process != PsGetCurrentProcess())
{
PageDirTable = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
Pde = (PULONGLONG)MmCreateHyperspaceMapping(PTE_TO_PFN(PageDirTable[i]));
- MmDeleteHyperspaceMapping(PageDirTable);
+ MmDeleteHyperspaceMapping(PageDirTable);
}
else
{
for (i = PAE_ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 4 * 512; i++)
{
if (!(i >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) && i < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) + 4) &&
- !(i >= PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE) && i < PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE) + 2) &&
- 0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
+ !(i >= PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE) && i < PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE) + 2) &&
+ 0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
{
(void)ExfpInterlockedExchange64UL(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]);
- if (Ke386GlobalPagesEnabled)
- {
+ if (Ke386GlobalPagesEnabled)
+ {
MmGlobalKernelPageDirectoryForPAE[i] |= PA_GLOBAL;
CurrentPageDirectory[i] |= PA_GLOBAL;
- }
- }
+ }
+ }
}
}
else
for (i = ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 1024; i++)
{
if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) &&
- i != ADDR_TO_PDE_OFFSET(HYPERSPACE) &&
+ i != ADDR_TO_PDE_OFFSET(HYPERSPACE) &&
0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i])
{
MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
- if (Ke386GlobalPagesEnabled)
- {
+ if (Ke386GlobalPagesEnabled)
+ {
MmGlobalKernelPageDirectory[i] |= PA_GLOBAL;
CurrentPageDirectory[i] |= PA_GLOBAL;
- }
+ }
}
}
}
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
- Ke386Pae ? 0x800000 : 0x400000,
+ Ke386Pae ? 0x800000 : 0x400000,
PAGE_READWRITE,
&kernel_map_desc,
TRUE,
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
- 0x400000,
+ 0x400000,
PAGE_READWRITE,
&hyperspace_desc,
TRUE,
PMEMORY_AREA *ParentReplace;
ULONG_PTR Address;
PVOID EndAddress;
-
+
if (MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3)
{
PEPROCESS CurrentProcess = PsGetCurrentProcess();
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
+
if (Process != NULL &&
Process != CurrentProcess)
{
{
ASSERT(MemoryArea->EndingAddress < MmSystemRangeStart);
ASSERT(MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY || MemoryArea->Type == MEMORY_AREA_SECTION_VIEW);
-
+
/* MmCleanProcessAddressSpace might have removed it (and this would be MmDeleteProcessAdressSpace) */
ASSERT(((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare != 0);
if (((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare == 1)
{
MiRemoveNode(MemoryArea->Vad, &Process->VadRoot);
}
-
+
ExFreePoolWithTag(MemoryArea->Vad, TAG_MVAD);
MemoryArea->Vad = NULL;
}
return STATUS_CONFLICTING_ADDRESSES;
}
}
-
+
//
// Is this a static memory area?
//
{
ULONG i;
NTSTATUS Status;
-
+
ASSERT(((ULONG_PTR)BaseAddress % PAGE_SIZE) == 0);
for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
PMMSUPPORT AddressSpace;
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
-
+
DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
break;
#ifdef NEWCC
- case MEMORY_AREA_CACHE:
- // This code locks for itself to keep from having to break a lock
- // passed in.
- if (!FromMdl)
- MmUnlockAddressSpace(AddressSpace);
- Status = MmAccessFaultCacheSection(Mode, Address, Locked);
- if (!FromMdl)
- MmLockAddressSpace(AddressSpace);
- break;
+ case MEMORY_AREA_CACHE:
+ // This code locks for itself to keep from having to break a lock
+ // passed in.
+ if (!FromMdl)
+ MmUnlockAddressSpace(AddressSpace);
+ Status = MmAccessFaultCacheSection(Mode, Address, Locked);
+ if (!FromMdl)
+ MmLockAddressSpace(AddressSpace);
+ break;
#endif
default:
*/
if (Mode != KernelMode)
{
- DPRINT1("Address: %x\n", Address);
+ DPRINT1("Address: %x\n", Address);
return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
break;
#ifdef NEWCC
- case MEMORY_AREA_CACHE:
- // This code locks for itself to keep from having to break a lock
- // passed in.
- if (!FromMdl)
- MmUnlockAddressSpace(AddressSpace);
- Status = MmNotPresentFaultCacheSection(Mode, Address, Locked);
- if (!FromMdl)
- MmLockAddressSpace(AddressSpace);
- break;
+ case MEMORY_AREA_CACHE:
+ // This code locks for itself to keep from having to break a lock
+ // passed in.
+ if (!FromMdl)
+ MmUnlockAddressSpace(AddressSpace);
+ Status = MmNotPresentFaultCacheSection(Mode, Address, Locked);
+ if (!FromMdl)
+ MmLockAddressSpace(AddressSpace);
+ break;
#endif
default:
}
#endif
}
-
+
/* Is there a ReactOS address space yet? */
if (MmGetKernelAddressSpace())
{
MemoryArea = MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address);
}
}
-
+
/* Is this an ARM3 memory area, or is there no address space yet? */
if (((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) ||
(!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) ||
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/mm/mminit.c
* PURPOSE: Memory Manager Initialization
- * PROGRAMMERS:
+ * PROGRAMMERS:
*/
/* INCLUDES ******************************************************************/
PMEMORY_AREA MArea;
NTSTATUS Status;
BoundaryAddressMultiple.QuadPart = 0;
-
+
//
// Create the memory area to define the PTE base
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// Create the memory area to define Hyperspace
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// Protect the PFN database
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// ReactOS requires a memory area to keep the initial NP area off-bounds
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// And we need one more for the system NP
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// We also need one for system view space
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// And another for session space
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// One more for ARM paged pool
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// Next, the KPCR
//
0,
BoundaryAddressMultiple);
ASSERT(Status == STATUS_SUCCESS);
-
+
//
// Now the KUSER_SHARED_DATA
//
DPRINT1(" 0x%p - 0x%p\t%s\n",
MiSystemViewStart,
(ULONG_PTR)MiSystemViewStart + MmSystemViewSize,
- "System View Space");
+ "System View Space");
DPRINT1(" 0x%p - 0x%p\t%s\n",
MmSessionBase,
MiSessionSpaceEnd,
PagesWritten = 0;
#ifndef NEWCC
- // XXX arty -- we flush when evicting pages or destorying cache
- // sections.
+ // XXX arty -- we flush when evicting pages or destorying cache
+ // sections.
CcRosFlushDirtyPages(128, &PagesWritten, FALSE);
#endif
}
KPRIORITY Priority;
NTSTATUS Status;
CLIENT_ID MpwThreadId;
-
+
KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE);
Status = PsCreateSystemThread(&MpwThreadHandle,
PMMPTE PointerPte;
MMPTE TempPte = ValidKernelPte;
PFN_NUMBER PageFrameNumber;
-
+
/* Initialize the kernel address space */
ASSERT(Phase == 1);
KeInitializeGuardedMutex(&PsIdleProcess->AddressCreationLock);
MmInitializePageOp();
MmInitSectionImplementation();
MmInitPagingFile();
-
+
//
// Create a PTE to double-map the shared data section. We allocate it
// from paged pool so that we can't fault when trying to touch the PTE
sizeof(MMPTE),
' mM');
if (!MmSharedUserDataPte) return FALSE;
-
+
//
// Now get the PTE for shared data, and read the PFN that holds it
//
PointerPte = MiAddressToPte((PVOID)KI_USER_SHARED_DATA);
ASSERT(PointerPte->u.Hard.Valid == 1);
PageFrameNumber = PFN_FROM_PTE(PointerPte);
-
+
/* Build the PTE and write it */
MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte,
PointerPte,
MM_READONLY,
PageFrameNumber);
*MmSharedUserDataPte = TempPte;
-
+
/* Setup the memory threshold events */
if (!MiInitializeMemoryEvents()) return FALSE;
-
+
/*
* Unmap low memory
*/
MiInitBalancerThread();
-
+
/*
* Initialise the modified page writer.
*/
MmInitMpwThread();
-
+
/* Initialize the balance set manager */
MmInitBsmThread();
if (i >= MAX_PAGING_FILES)
{
- DPRINT1("Bad swap entry 0x%.8X\n", Entry);
- KeBugCheck(MEMORY_MANAGEMENT);
+ DPRINT1("Bad swap entry 0x%.8X\n", Entry);
+ KeBugCheck(MEMORY_MANAGEMENT);
}
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
ULONG_PTR Hash;
KIRQL oldIrql;
PMM_PAGEOP PageOp;
-
+
Address = (PVOID)PAGE_ROUND_DOWN(Address);
Offset = PAGE_ROUND_DOWN(Offset);
#define PA_CD 0x10
#define PA_READWRITE 3
-#define HYPERSPACE (0xc0400000)
-#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
+#define HYPERSPACE (0xc0400000)
+#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
#define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
#define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
{
PEPROCESS CurrentProcess = PsGetCurrentProcess();
- DPRINT1("DeletePageTable: Process: %x CurrentProcess %x\n",
+ DPRINT1("DeletePageTable: Process: %x CurrentProcess %x\n",
Process, CurrentProcess);
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(&Process->Pcb);
}
-
+
if (Process)
{
DPRINT1("Revoking VSID %d\n", (paddr_t)Process->UniqueProcessId);
{
DPRINT1("No vsid to revoke\n");
}
-
+
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
- }
+ }
}
VOID
ppc_map_info_t info = { 0 };
DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
- Process, Address, FreePage, WasDirty, Page);
+ Process, Address, FreePage, WasDirty, Page);
info.proc = Process ? (int)Process->UniqueProcessId : 0;
info.addr = (vaddr_t)Address;
if (FreePage && info.phys)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, info.phys >> PAGE_SHIFT);
+ MmReleasePageMemoryConsumer(MC_NPPOOL, info.phys >> PAGE_SHIFT);
}
/*
*/
if (WasDirty != NULL)
{
- *WasDirty = !!(info.flags & MMU_PAGE_DIRTY);
+ *WasDirty = !!(info.flags & MMU_PAGE_DIRTY);
}
if (Page != NULL)
{
- *Page = info.phys >> PAGE_SHIFT;
+ *Page = info.phys >> PAGE_SHIFT;
}
}
* Decrement the reference count for this page table.
*/
if (Process != NULL &&
- ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
- Address < MmSystemRangeStart)
+ ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
+ Address < MmSystemRangeStart)
{
- PUSHORT Ptrc;
+ PUSHORT Ptrc;
- Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
- MmFreePageTable(Process, Address);
+ Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
+ MmFreePageTable(Process, Address);
}
/*
if (Address < MmSystemRangeStart && Process == NULL)
{
- DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n");
- ASSERT(FALSE);
+ DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n");
+ ASSERT(FALSE);
}
info.proc = Process ? (int)Process->UniqueProcessId : 0;
MmCreateVirtualMappingForKernel(PVOID Address,
ULONG flProtect,
PPFN_NUMBER Pages,
- ULONG PageCount)
+ ULONG PageCount)
{
ULONG i;
PVOID Addr;
if (Address < MmSystemRangeStart)
{
- DPRINT1("MmCreateVirtualMappingForKernel is called for user space\n");
- ASSERT(FALSE);
+ DPRINT1("MmCreateVirtualMappingForKernel is called for user space\n");
+ ASSERT(FALSE);
}
Addr = Address;
for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
{
#if 0
- if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
- {
+ 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);
- }
- (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
+ }
+ (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
#endif
}
{
if (Process == NULL && Address < MmSystemRangeStart)
{
- DPRINT1("No process\n");
- ASSERT(FALSE);
+ DPRINT1("No process\n");
+ ASSERT(FALSE);
}
if (Process != NULL && Address >= MmSystemRangeStart)
{
- DPRINT1("Setting kernel address with process context\n");
- ASSERT(FALSE);
+ DPRINT1("Setting kernel address with process context\n");
+ ASSERT(FALSE);
}
if (SwapEntry & (1 << 31))
{
- ASSERT(FALSE);
+ ASSERT(FALSE);
}
// XXX arty
ppc_map_info_t info = { 0 };
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
- Process, Address, flProtect, Pages, *Pages, PageCount);
+ 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);
- }
+ 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);
- }
+ 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 = ProtectToFlags(flProtect);
for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
{
- Process = PsGetCurrentProcess();
- info.proc = ((Addr < MmSystemRangeStart) && Process) ?
+ Process = PsGetCurrentProcess();
+ info.proc = ((Addr < MmSystemRangeStart) && Process) ?
(int)Process->UniqueProcessId : 0;
- info.addr = (vaddr_t)Addr;
- info.flags = Attributes;
- MmuMapPage(&info, 1);
- //(void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
- if (Address < MmSystemRangeStart &&
- ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
- Attributes & PA_PRESENT)
- {
+ info.addr = (vaddr_t)Addr;
+ info.flags = Attributes;
+ MmuMapPage(&info, 1);
+ //(void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
+ if (Address < MmSystemRangeStart &&
+ ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
+ Attributes & PA_PRESENT)
+ {
#if 0
PUSHORT Ptrc;
Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++;
#endif
- }
+ }
}
return(STATUS_SUCCESS);
}
if (!info.phys) { return PAGE_NOACCESS; }
if (!(info.flags & MMU_KMASK))
{
- Protect |= PAGE_SYSTEM;
- if ((info.flags & MMU_KR) && (info.flags & MMU_KW))
- Protect = PAGE_READWRITE;
- else if (info.flags & MMU_KR)
- Protect = PAGE_EXECUTE_READ;
+ Protect |= PAGE_SYSTEM;
+ if ((info.flags & MMU_KR) && (info.flags & MMU_KW))
+ Protect = PAGE_READWRITE;
+ else if (info.flags & MMU_KR)
+ Protect = PAGE_EXECUTE_READ;
}
else
{
- if ((info.flags & MMU_UR) && (info.flags & MMU_UW))
- Protect = PAGE_READWRITE;
- else
- Protect = PAGE_EXECUTE_READ;
+ if ((info.flags & MMU_UR) && (info.flags & MMU_UW))
+ Protect = PAGE_READWRITE;
+ else
+ Protect = PAGE_EXECUTE_READ;
}
return(Protect);
}
/* get the faulting address */
if (trap == 4) /* Instruction miss */
- VirtualAddr = frame->srr0;
+ VirtualAddr = frame->srr0;
else /* Data miss */
- VirtualAddr = frame->dar;
+ VirtualAddr = frame->dar;
/* MSR_PR */
Mode = frame->srr1 & 0x4000 ? UserMode : KernelMode;
/* handle the fault */
if (AccessFault)
{
- Status = MmAccessFault(Mode, (PVOID)VirtualAddr, FALSE, TrapInfo);
+ Status = MmAccessFault(Mode, (PVOID)VirtualAddr, FALSE, TrapInfo);
}
else
{
- Status = MmNotPresentFault(Mode, VirtualAddr, FALSE);
+ Status = MmNotPresentFault(Mode, VirtualAddr, FALSE);
}
if (NT_SUCCESS(Status))
while (current_entry != NULL)
{
#ifdef NEWCC
- if (!RMAP_IS_SEGMENT(current_entry->Address))
+ if (!RMAP_IS_SEGMENT(current_entry->Address))
#endif
- MmSetCleanPage(current_entry->Process, current_entry->Address);
- current_entry = current_entry->Next;
+ MmSetCleanPage(current_entry->Process, current_entry->Address);
+ current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
}
while (current_entry != NULL)
{
#ifdef NEWCC
- if (!RMAP_IS_SEGMENT(current_entry->Address))
+ if (!RMAP_IS_SEGMENT(current_entry->Address))
#endif
- MmSetDirtyPage(current_entry->Process, current_entry->Address);
+ MmSetDirtyPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
}
while (current_entry != NULL)
{
- if (
+ if (
#ifdef NEWCC
- !RMAP_IS_SEGMENT(current_entry->Address) &&
+ !RMAP_IS_SEGMENT(current_entry->Address) &&
#endif
- MmIsDirtyPage(current_entry->Process, current_entry->Address))
+ MmIsDirtyPage(current_entry->Process, current_entry->Address))
{
ExReleaseFastMutex(&RmapListLock);
return(TRUE);
#ifdef NEWCC
if (!RMAP_IS_SEGMENT(Address))
#endif
- Address = (PVOID)PAGE_ROUND_DOWN(Address);
+ Address = (PVOID)PAGE_ROUND_DOWN(Address);
new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList);
if (new_entry == NULL)
#ifdef NEWCC
!RMAP_IS_SEGMENT(Address) &&
#endif
- MmGetPfnForProcess(Process, Address) != Page)
+ MmGetPfnForProcess(Process, Address) != Page)
{
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
"address 0x%.8X\n", Process->UniqueProcessId, Address,
if (!RMAP_IS_SEGMENT(Address))
#endif
{
- if (Process == NULL)
- {
- Process = PsInitialSystemProcess;
- }
- if (Process)
- {
- PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
- if (PrevSize >= Process->Vm.PeakWorkingSetSize)
- {
- Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
- }
- }
+ if (Process == NULL)
+ {
+ Process = PsInitialSystemProcess;
+ }
+ if (Process)
+ {
+ PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
+ if (PrevSize >= Process->Vm.PeakWorkingSetSize)
+ {
+ Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
+ }
+ }
}
}
previous_entry = current_entry;
current_entry = current_entry->Next;
#ifdef NEWCC
- if (!RMAP_IS_SEGMENT(previous_entry->Address))
+ if (!RMAP_IS_SEGMENT(previous_entry->Address))
#endif
- {
- if (DeleteMapping)
- {
- DeleteMapping(Context, previous_entry->Process,
- previous_entry->Address);
- }
- Process = previous_entry->Process;
- ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
- if (Process == NULL)
- {
- Process = PsInitialSystemProcess;
- }
- if (Process)
- {
- (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
- }
- }
+ {
+ if (DeleteMapping)
+ {
+ DeleteMapping(Context, previous_entry->Process,
+ previous_entry->Address);
+ }
+ Process = previous_entry->Process;
+ ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
+ if (Process == NULL)
+ {
+ Process = PsInitialSystemProcess;
+ }
+ if (Process)
+ {
+ (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
+ }
+ }
#ifdef NEWCC
- else
- {
- ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
- }
+ else
+ {
+ ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
+ }
#endif
}
}
ExReleaseFastMutex(&RmapListLock);
ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
#ifdef NEWCC
- if (!RMAP_IS_SEGMENT(Address))
+ if (!RMAP_IS_SEGMENT(Address))
#endif
- {
- if (Process == NULL)
- {
- Process = PsInitialSystemProcess;
- }
- if (Process)
- {
- (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
- }
- }
+ {
+ if (Process == NULL)
+ {
+ Process = PsInitialSystemProcess;
+ }
+ if (Process)
+ {
+ (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
+ }
+ }
return;
}
previous_entry = current_entry;
current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL)
{
- if (RMAP_IS_SEGMENT(current_entry->Address))
+ if (RMAP_IS_SEGMENT(current_entry->Address))
{
- Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process;
- *RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK;
- InterlockedIncrementUL(&Result->Segment->ReferenceCount);
+ Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process;
+ *RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK;
+ InterlockedIncrementUL(&Result->Segment->ReferenceCount);
ExReleaseFastMutex(&RmapListLock);
- return Result;
+ return Result;
}
previous_entry = current_entry;
current_entry = current_entry->Next;
current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL)
{
- if (RMAP_IS_SEGMENT(current_entry->Address))
+ if (RMAP_IS_SEGMENT(current_entry->Address))
{
if (previous_entry == NULL)
{
File Format Specification", revision 6.0 (February 1999)
*/
NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
- IN SIZE_T FileHeaderSize,
- IN PVOID File,
- OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
- OUT PULONG Flags,
- IN PEXEFMT_CB_READ_FILE ReadFileCb,
- IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb)
+ IN SIZE_T FileHeaderSize,
+ IN PVOID File,
+ OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject,
+ OUT PULONG Flags,
+ IN PEXEFMT_CB_READ_FILE ReadFileCb,
+ IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb)
{
NTSTATUS nStatus;
ULONG cbFileHeaderOffsetSize = 0;
/* image too small to be an MZ executable */
if(FileHeaderSize < sizeof(IMAGE_DOS_HEADER))
- DIE(("Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
+ DIE(("Too small to be an MZ executable, size is %lu\n", FileHeaderSize));
/* no MZ signature */
if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
- DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
+ DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
/* not a Windows executable */
if(pidhDosHeader->e_lfanew <= 0)
- DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
+ DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
/* NT HEADER */
nStatus = STATUS_INVALID_IMAGE_FORMAT;
if(!Intsafe_AddULong32(&cbFileHeaderOffsetSize, pidhDosHeader->e_lfanew, RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)))
- DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+ DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
if(FileHeaderSize < cbFileHeaderOffsetSize)
- pinhNtHeader = NULL;
+ pinhNtHeader = NULL;
else
{
- /*
- * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
- * and FileHeaderSize >= cbFileHeaderOffsetSize, so this holds true too
- */
- ASSERT(Intsafe_CanOffsetPointer(FileHeader, pidhDosHeader->e_lfanew));
- pinhNtHeader = (PVOID)((UINT_PTR)FileHeader + pidhDosHeader->e_lfanew);
+ /*
+ * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
+ * and FileHeaderSize >= cbFileHeaderOffsetSize, so this holds true too
+ */
+ ASSERT(Intsafe_CanOffsetPointer(FileHeader, pidhDosHeader->e_lfanew));
+ pinhNtHeader = (PVOID)((UINT_PTR)FileHeader + pidhDosHeader->e_lfanew);
}
/*
if(FileHeaderSize < cbFileHeaderOffsetSize ||
(UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
{
- ULONG cbNtHeaderSize;
- ULONG cbReadSize;
- PVOID pData;
+ ULONG cbNtHeaderSize;
+ ULONG cbReadSize;
+ PVOID pData;
l_ReadHeaderFromFile:
- cbNtHeaderSize = 0;
- lnOffset.QuadPart = pidhDosHeader->e_lfanew;
+ cbNtHeaderSize = 0;
+ lnOffset.QuadPart = pidhDosHeader->e_lfanew;
- /* read the header from the file */
- nStatus = ReadFileCb(File, &lnOffset, sizeof(IMAGE_NT_HEADERS64), &pData, &pBuffer, &cbReadSize);
+ /* read the header from the file */
+ nStatus = ReadFileCb(File, &lnOffset, sizeof(IMAGE_NT_HEADERS64), &pData, &pBuffer, &cbReadSize);
- if(!NT_SUCCESS(nStatus))
- DIE(("ReadFile failed, status %08X\n", nStatus));
+ if(!NT_SUCCESS(nStatus))
+ DIE(("ReadFile failed, status %08X\n", nStatus));
- ASSERT(pData);
- ASSERT(pBuffer);
- ASSERT(cbReadSize > 0);
+ ASSERT(pData);
+ ASSERT(pBuffer);
+ ASSERT(cbReadSize > 0);
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
+ nStatus = STATUS_INVALID_IMAGE_FORMAT;
- /* the buffer doesn't contain the file header */
- if(cbReadSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader))
- DIE(("The file doesn't contain the PE file header\n"));
+ /* the buffer doesn't contain the file header */
+ if(cbReadSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader))
+ DIE(("The file doesn't contain the PE file header\n"));
- pinhNtHeader = pData;
+ pinhNtHeader = pData;
- /* object still not aligned: copy it to the beginning of the buffer */
- if((UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
- {
- ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) == 0);
- RtlMoveMemory(pBuffer, pData, cbReadSize);
- pinhNtHeader = pBuffer;
- }
+ /* object still not aligned: copy it to the beginning of the buffer */
+ if((UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0)
+ {
+ ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) == 0);
+ RtlMoveMemory(pBuffer, pData, cbReadSize);
+ pinhNtHeader = pBuffer;
+ }
- /* invalid NT header */
- nStatus = STATUS_INVALID_IMAGE_PROTECT;
+ /* invalid NT header */
+ nStatus = STATUS_INVALID_IMAGE_PROTECT;
- if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
- DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
+ if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
+ DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
+ nStatus = STATUS_INVALID_IMAGE_FORMAT;
- if(!Intsafe_AddULong32(&cbNtHeaderSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
- DIE(("The full NT header is too large\n"));
+ if(!Intsafe_AddULong32(&cbNtHeaderSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+ DIE(("The full NT header is too large\n"));
- /* the buffer doesn't contain the whole NT header */
- if(cbReadSize < cbNtHeaderSize)
- DIE(("The file doesn't contain the full NT header\n"));
+ /* the buffer doesn't contain the whole NT header */
+ if(cbReadSize < cbNtHeaderSize)
+ DIE(("The file doesn't contain the full NT header\n"));
}
else
{
- ULONG cbOptHeaderOffsetSize = 0;
+ ULONG cbOptHeaderOffsetSize = 0;
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
+ nStatus = STATUS_INVALID_IMAGE_FORMAT;
- /* don't trust an invalid NT header */
- if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
- DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
+ /* don't trust an invalid NT header */
+ if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
+ DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
- if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
- DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
+ if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
+ DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
- if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
- DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
+ if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
+ DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
- /* the buffer doesn't contain the whole NT header: read it from the file */
- if(cbOptHeaderOffsetSize > FileHeaderSize)
- goto l_ReadHeaderFromFile;
+ /* the buffer doesn't contain the whole NT header: read it from the file */
+ if(cbOptHeaderOffsetSize > FileHeaderSize)
+ goto l_ReadHeaderFromFile;
}
/* read information from the NT header */
nStatus = STATUS_INVALID_IMAGE_FORMAT;
if(!RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Magic))
- DIE(("The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
+ DIE(("The optional header doesn't contain the Magic field, SizeOfOptionalHeader is %X\n", cbOptHeaderSize));
/* ASSUME: RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject)); */
switch(piohOptHeader->Magic)
{
- case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
- case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
- break;
+ case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+ case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+ break;
- default:
- DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
+ default:
+ DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
}
if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SectionAlignment) &&
RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment))
{
- /* See [1], section 3.4.2 */
- if(piohOptHeader->SectionAlignment < PAGE_SIZE)
- {
- if(piohOptHeader->FileAlignment != piohOptHeader->SectionAlignment)
- DIE(("Sections aren't page-aligned and the file alignment isn't the same\n"));
- }
- else if(piohOptHeader->SectionAlignment < piohOptHeader->FileAlignment)
- DIE(("The section alignment is smaller than the file alignment\n"));
-
- nSectionAlignment = piohOptHeader->SectionAlignment;
- nFileAlignment = piohOptHeader->FileAlignment;
-
- if(!IsPowerOf2(nSectionAlignment) || !IsPowerOf2(nFileAlignment))
- DIE(("The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
+ /* See [1], section 3.4.2 */
+ if(piohOptHeader->SectionAlignment < PAGE_SIZE)
+ {
+ if(piohOptHeader->FileAlignment != piohOptHeader->SectionAlignment)
+ DIE(("Sections aren't page-aligned and the file alignment isn't the same\n"));
+ }
+ else if(piohOptHeader->SectionAlignment < piohOptHeader->FileAlignment)
+ DIE(("The section alignment is smaller than the file alignment\n"));
+
+ nSectionAlignment = piohOptHeader->SectionAlignment;
+ nFileAlignment = piohOptHeader->FileAlignment;
+
+ if(!IsPowerOf2(nSectionAlignment) || !IsPowerOf2(nFileAlignment))
+ DIE(("The section alignment (%u) and file alignment (%u) aren't both powers of 2\n", nSectionAlignment, nFileAlignment));
}
else
{
- nSectionAlignment = PAGE_SIZE;
- nFileAlignment = PAGE_SIZE;
+ nSectionAlignment = PAGE_SIZE;
+ nFileAlignment = PAGE_SIZE;
}
ASSERT(IsPowerOf2(nSectionAlignment));
switch(piohOptHeader->Magic)
{
- /* PE32 */
- case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
- {
- if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase))
- ImageSectionObject->ImageBase = piohOptHeader->ImageBase;
+ /* PE32 */
+ case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+ {
+ if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase))
+ ImageSectionObject->ImageBase = piohOptHeader->ImageBase;
- if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage))
- ImageSectionObject->ImageSize = piohOptHeader->SizeOfImage;
+ if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage))
+ ImageSectionObject->ImageSize = piohOptHeader->SizeOfImage;
- if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve))
- ImageSectionObject->StackReserve = piohOptHeader->SizeOfStackReserve;
+ if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve))
+ ImageSectionObject->StackReserve = piohOptHeader->SizeOfStackReserve;
- if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit))
- ImageSectionObject->StackCommit = piohOptHeader->SizeOfStackCommit;
+ if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit))
+ ImageSectionObject->StackCommit = piohOptHeader->SizeOfStackCommit;
- break;
- }
+ break;
+ }
- /* PE32+ */
- case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
- {
- const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
+ /* PE32+ */
+ case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+ {
+ const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader;
- pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader;
+ pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader;
- if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase))
- {
- if(pioh64OptHeader->ImageBase > MAXULONG_PTR)
- DIE(("ImageBase exceeds the address space\n"));
+ if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase))
+ {
+ if(pioh64OptHeader->ImageBase > MAXULONG_PTR)
+ DIE(("ImageBase exceeds the address space\n"));
- ImageSectionObject->ImageBase = (ULONG_PTR)pioh64OptHeader->ImageBase;
- }
+ ImageSectionObject->ImageBase = (ULONG_PTR)pioh64OptHeader->ImageBase;
+ }
- if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage))
- {
- if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR)
- DIE(("SizeOfImage exceeds the address space\n"));
+ if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage))
+ {
+ if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR)
+ DIE(("SizeOfImage exceeds the address space\n"));
- ImageSectionObject->ImageSize = pioh64OptHeader->SizeOfImage;
- }
+ ImageSectionObject->ImageSize = pioh64OptHeader->SizeOfImage;
+ }
- if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve))
- {
- if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR)
- DIE(("SizeOfStackReserve exceeds the address space\n"));
+ if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve))
+ {
+ if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR)
+ DIE(("SizeOfStackReserve exceeds the address space\n"));
- ImageSectionObject->StackReserve = (ULONG_PTR)pioh64OptHeader->SizeOfStackReserve;
- }
+ ImageSectionObject->StackReserve = (ULONG_PTR)pioh64OptHeader->SizeOfStackReserve;
+ }
- if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit))
- {
- if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR)
- DIE(("SizeOfStackCommit exceeds the address space\n"));
+ if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit))
+ {
+ if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR)
+ DIE(("SizeOfStackCommit exceeds the address space\n"));
- ImageSectionObject->StackCommit = (ULONG_PTR)pioh64OptHeader->SizeOfStackCommit;
- }
+ ImageSectionObject->StackCommit = (ULONG_PTR)pioh64OptHeader->SizeOfStackCommit;
+ }
- break;
- }
+ break;
+ }
}
/* [1], section 3.4.2 */
if((ULONG_PTR)ImageSectionObject->ImageBase % 0x10000)
- DIE(("ImageBase is not aligned on a 64KB boundary"));
+ DIE(("ImageBase is not aligned on a 64KB boundary"));
if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem))
{
- ImageSectionObject->Subsystem = piohOptHeader->Subsystem;
-
- if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
- RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MajorSubsystemVersion))
- {
- ImageSectionObject->MinorSubsystemVersion = piohOptHeader->MinorSubsystemVersion;
- ImageSectionObject->MajorSubsystemVersion = piohOptHeader->MajorSubsystemVersion;
- }
+ ImageSectionObject->Subsystem = piohOptHeader->Subsystem;
+
+ if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) &&
+ RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MajorSubsystemVersion))
+ {
+ ImageSectionObject->MinorSubsystemVersion = piohOptHeader->MinorSubsystemVersion;
+ ImageSectionObject->MajorSubsystemVersion = piohOptHeader->MajorSubsystemVersion;
+ }
}
if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint))
{
- ImageSectionObject->EntryPoint = piohOptHeader->ImageBase +
+ ImageSectionObject->EntryPoint = piohOptHeader->ImageBase +
piohOptHeader->AddressOfEntryPoint;
}
if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode))
- ImageSectionObject->Executable = piohOptHeader->SizeOfCode != 0;
+ ImageSectionObject->Executable = piohOptHeader->SizeOfCode != 0;
else
- ImageSectionObject->Executable = TRUE;
+ ImageSectionObject->Executable = TRUE;
ImageSectionObject->ImageCharacteristics = pinhNtHeader->FileHeader.Characteristics;
ImageSectionObject->Machine = pinhNtHeader->FileHeader.Machine;
/* see [1], section 3.3 */
if(pinhNtHeader->FileHeader.NumberOfSections > 96)
- DIE(("Too many sections, NumberOfSections is %u\n", pinhNtHeader->FileHeader.NumberOfSections));
+ DIE(("Too many sections, NumberOfSections is %u\n", pinhNtHeader->FileHeader.NumberOfSections));
/*
* the additional segment is for the file's headers. They need to be present for
/* file offset for the section headers */
if(!Intsafe_AddULong32(&cbSectionHeadersOffset, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
- DIE(("Offset overflow\n"));
+ DIE(("Offset overflow\n"));
if(!Intsafe_AddULong32(&cbSectionHeadersOffset, cbSectionHeadersOffset, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
- DIE(("Offset overflow\n"));
+ DIE(("Offset overflow\n"));
/* size of the section headers */
ASSERT(Intsafe_CanMulULong32(pinhNtHeader->FileHeader.NumberOfSections, sizeof(IMAGE_SECTION_HEADER)));
cbSectionHeadersSize = pinhNtHeader->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
if(!Intsafe_AddULong32(&cbSectionHeadersOffsetSize, cbSectionHeadersOffset, cbSectionHeadersSize))
- DIE(("Section headers too large\n"));
+ DIE(("Section headers too large\n"));
/* size of the executable's headers */
if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfHeaders))
{
-// if(!IsAligned(piohOptHeader->SizeOfHeaders, nFileAlignment))
-// DIE(("SizeOfHeaders is not aligned\n"));
+// if(!IsAligned(piohOptHeader->SizeOfHeaders, nFileAlignment))
+// DIE(("SizeOfHeaders is not aligned\n"));
- if(cbSectionHeadersSize > piohOptHeader->SizeOfHeaders)
- DIE(("The section headers overflow SizeOfHeaders\n"));
+ if(cbSectionHeadersSize > piohOptHeader->SizeOfHeaders)
+ DIE(("The section headers overflow SizeOfHeaders\n"));
- cbHeadersSize = piohOptHeader->SizeOfHeaders;
+ cbHeadersSize = piohOptHeader->SizeOfHeaders;
}
else if(!AlignUp(&cbHeadersSize, cbSectionHeadersOffsetSize, nFileAlignment))
- DIE(("Overflow aligning the size of headers\n"));
+ DIE(("Overflow aligning the size of headers\n"));
if(pBuffer)
{
- ExFreePool(pBuffer);
- pBuffer = NULL;
+ ExFreePool(pBuffer);
+ pBuffer = NULL;
}
/* WARNING: pinhNtHeader IS NO LONGER USABLE */
/* WARNING: piohOptHeader IS NO LONGER USABLE */
/* WARNING: pioh64OptHeader IS NO LONGER USABLE */
if(FileHeaderSize < cbSectionHeadersOffsetSize)
- pishSectionHeaders = NULL;
+ pishSectionHeaders = NULL;
else
{
- /*
- * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
- * and FileHeaderSize >= cbSectionHeadersOffsetSize, so this holds true too
- */
- ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbSectionHeadersOffset));
- pishSectionHeaders = (PVOID)((UINT_PTR)FileHeader + cbSectionHeadersOffset);
+ /*
+ * we already know that Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize),
+ * and FileHeaderSize >= cbSectionHeadersOffsetSize, so this holds true too
+ */
+ ASSERT(Intsafe_CanOffsetPointer(FileHeader, cbSectionHeadersOffset));
+ pishSectionHeaders = (PVOID)((UINT_PTR)FileHeader + cbSectionHeadersOffset);
}
/*
if(FileHeaderSize < cbSectionHeadersOffsetSize ||
(UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
{
- PVOID pData;
- ULONG cbReadSize;
+ PVOID pData;
+ ULONG cbReadSize;
- lnOffset.QuadPart = cbSectionHeadersOffset;
+ lnOffset.QuadPart = cbSectionHeadersOffset;
- /* read the header from the file */
- nStatus = ReadFileCb(File, &lnOffset, cbSectionHeadersSize, &pData, &pBuffer, &cbReadSize);
+ /* read the header from the file */
+ nStatus = ReadFileCb(File, &lnOffset, cbSectionHeadersSize, &pData, &pBuffer, &cbReadSize);
- if(!NT_SUCCESS(nStatus))
- DIE(("ReadFile failed with status %08X\n", nStatus));
+ if(!NT_SUCCESS(nStatus))
+ DIE(("ReadFile failed with status %08X\n", nStatus));
- ASSERT(pData);
- ASSERT(pBuffer);
- ASSERT(cbReadSize > 0);
+ ASSERT(pData);
+ ASSERT(pBuffer);
+ ASSERT(cbReadSize > 0);
- nStatus = STATUS_INVALID_IMAGE_FORMAT;
+ nStatus = STATUS_INVALID_IMAGE_FORMAT;
- /* the buffer doesn't contain all the section headers */
- if(cbReadSize < cbSectionHeadersSize)
- DIE(("The file doesn't contain all of the section headers\n"));
+ /* the buffer doesn't contain all the section headers */
+ if(cbReadSize < cbSectionHeadersSize)
+ DIE(("The file doesn't contain all of the section headers\n"));
- pishSectionHeaders = pData;
+ pishSectionHeaders = pData;
- /* object still not aligned: copy it to the beginning of the buffer */
- if((UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
- {
- ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) == 0);
- RtlMoveMemory(pBuffer, pData, cbReadSize);
- pishSectionHeaders = pBuffer;
- }
+ /* object still not aligned: copy it to the beginning of the buffer */
+ if((UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0)
+ {
+ ASSERT((UINT_PTR)pBuffer % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) == 0);
+ RtlMoveMemory(pBuffer, pData, cbReadSize);
+ pishSectionHeaders = pBuffer;
+ }
}
/* SEGMENTS */
DIE(("AllocateSegments failed\n"));
/* initialize the headers segment */
- pssSegments = ImageSectionObject->Segments;
+ pssSegments = ImageSectionObject->Segments;
// ASSERT(IsAligned(cbHeadersSize, nFileAlignment));
/* convert the executable sections into segments. See also [1], section 4 */
for(i = 0; i < ImageSectionObject->NrSegments - 1; ++ i)
{
- ULONG nCharacteristics;
+ ULONG nCharacteristics;
- /* validate the alignment */
- if(!IsAligned(pishSectionHeaders[i].VirtualAddress, nSectionAlignment))
- DIE(("VirtualAddress[%u] is not aligned\n", i));
+ /* validate the alignment */
+ if(!IsAligned(pishSectionHeaders[i].VirtualAddress, nSectionAlignment))
+ DIE(("VirtualAddress[%u] is not aligned\n", i));
- /* sections must be contiguous, ordered by base address and non-overlapping */
- if(pishSectionHeaders[i].VirtualAddress != nPrevVirtualEndOfSegment)
- DIE(("Memory gap between section %u and the previous\n", i));
+ /* sections must be contiguous, ordered by base address and non-overlapping */
+ if(pishSectionHeaders[i].VirtualAddress != nPrevVirtualEndOfSegment)
+ DIE(("Memory gap between section %u and the previous\n", i));
- /* ignore explicit BSS sections */
- if(pishSectionHeaders[i].SizeOfRawData != 0)
- {
- /* validate the alignment */
+ /* ignore explicit BSS sections */
+ if(pishSectionHeaders[i].SizeOfRawData != 0)
+ {
+ /* validate the alignment */
#if 0
- /* Yes, this should be a multiple of FileAlignment, but there's
- * stuff out there that isn't. We can cope with that
- */
- if(!IsAligned(pishSectionHeaders[i].SizeOfRawData, nFileAlignment))
- DIE(("SizeOfRawData[%u] is not aligned\n", i));
+ /* Yes, this should be a multiple of FileAlignment, but there's
+ * stuff out there that isn't. We can cope with that
+ */
+ if(!IsAligned(pishSectionHeaders[i].SizeOfRawData, nFileAlignment))
+ DIE(("SizeOfRawData[%u] is not aligned\n", i));
#endif
-// if(!IsAligned(pishSectionHeaders[i].PointerToRawData, nFileAlignment))
-// DIE(("PointerToRawData[%u] is not aligned\n", i));
+// if(!IsAligned(pishSectionHeaders[i].PointerToRawData, nFileAlignment))
+// DIE(("PointerToRawData[%u] is not aligned\n", i));
- /* conversion */
- pssSegments[i].FileOffset = pishSectionHeaders[i].PointerToRawData;
- pssSegments[i].RawLength = pishSectionHeaders[i].SizeOfRawData;
- }
- else
- {
- ASSERT(pssSegments[i].FileOffset == 0);
- ASSERT(pssSegments[i].RawLength == 0);
- }
+ /* conversion */
+ pssSegments[i].FileOffset = pishSectionHeaders[i].PointerToRawData;
+ pssSegments[i].RawLength = pishSectionHeaders[i].SizeOfRawData;
+ }
+ else
+ {
+ ASSERT(pssSegments[i].FileOffset == 0);
+ ASSERT(pssSegments[i].RawLength == 0);
+ }
- ASSERT(Intsafe_CanAddLong64(pssSegments[i].FileOffset, pssSegments[i].RawLength));
+ ASSERT(Intsafe_CanAddLong64(pssSegments[i].FileOffset, pssSegments[i].RawLength));
- nCharacteristics = pishSectionHeaders[i].Characteristics;
+ nCharacteristics = pishSectionHeaders[i].Characteristics;
- /* no explicit protection */
- if((nCharacteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == 0)
- {
- if(nCharacteristics & IMAGE_SCN_CNT_CODE)
- nCharacteristics |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
+ /* no explicit protection */
+ if((nCharacteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == 0)
+ {
+ if(nCharacteristics & IMAGE_SCN_CNT_CODE)
+ nCharacteristics |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
- if(nCharacteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
- nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+ if(nCharacteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
+ nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
- if(nCharacteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
- nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
- }
+ if(nCharacteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+ }
- /* see table above */
- pssSegments[i].Protection = SectionCharacteristicsToProtect[nCharacteristics >> 28];
- pssSegments[i].WriteCopy = !(nCharacteristics & IMAGE_SCN_MEM_SHARED);
+ /* see table above */
+ pssSegments[i].Protection = SectionCharacteristicsToProtect[nCharacteristics >> 28];
+ pssSegments[i].WriteCopy = !(nCharacteristics & IMAGE_SCN_MEM_SHARED);
- if(pishSectionHeaders[i].Misc.VirtualSize == 0 || pishSectionHeaders[i].Misc.VirtualSize < pishSectionHeaders[i].SizeOfRawData)
- pssSegments[i].Length = pishSectionHeaders[i].SizeOfRawData;
- else
- pssSegments[i].Length = pishSectionHeaders[i].Misc.VirtualSize;
+ if(pishSectionHeaders[i].Misc.VirtualSize == 0 || pishSectionHeaders[i].Misc.VirtualSize < pishSectionHeaders[i].SizeOfRawData)
+ pssSegments[i].Length = pishSectionHeaders[i].SizeOfRawData;
+ else
+ pssSegments[i].Length = pishSectionHeaders[i].Misc.VirtualSize;
pssSegments[i].Length = ALIGN_UP_BY(pssSegments[i].Length, nSectionAlignment);
if (pssSegments[i].Length < pssSegments[i].Length)
- DIE(("Cannot align the virtual size of section %u\n", i));
+ DIE(("Cannot align the virtual size of section %u\n", i));
- if(pssSegments[i].Length == 0)
- DIE(("Virtual size of section %u is null\n", i));
+ if(pssSegments[i].Length == 0)
+ DIE(("Virtual size of section %u is null\n", i));
- pssSegments[i].VirtualAddress = pishSectionHeaders[i].VirtualAddress;
- pssSegments[i].Characteristics = pishSectionHeaders[i].Characteristics;
+ pssSegments[i].VirtualAddress = pishSectionHeaders[i].VirtualAddress;
+ pssSegments[i].Characteristics = pishSectionHeaders[i].Characteristics;
- /* ensure the memory image is no larger than 4GB */
- nPrevVirtualEndOfSegment = pssSegments[i].VirtualAddress + pssSegments[i].Length;
- if (nPrevVirtualEndOfSegment < pssSegments[i].VirtualAddress)
- DIE(("The image is too large\n"));
+ /* ensure the memory image is no larger than 4GB */
+ nPrevVirtualEndOfSegment = pssSegments[i].VirtualAddress + pssSegments[i].Length;
+ if (nPrevVirtualEndOfSegment < pssSegments[i].VirtualAddress)
+ DIE(("The image is too large\n"));
}
if(nSectionAlignment >= PAGE_SIZE)
- *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED;
+ *Flags |= EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED;
/* Success */
nStatus = STATUS_ROS_EXEFMT_LOADED_FORMAT | EXEFMT_LOADED_PE32;
l_Return:
if(pBuffer)
- ExFreePool(pBuffer);
+ ExFreePool(pBuffer);
return nStatus;
}
#ifndef NEWCC
Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty);
#else
- Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
#endif
if (!NT_SUCCESS(Status))
{
Resources.Context = MemoryArea->Data.SectionData.Section->FileObject;
Resources.FileOffset.QuadPart = SegOffset +
- MemoryArea->Data.SectionData.Segment->FileOffset;
+ MemoryArea->Data.SectionData.Segment->FileOffset;
Resources.Consumer = MC_USER;
Resources.Amount = PAGE_SIZE;
{
return(STATUS_SUCCESS);
}
-
+
/*
* Check for the virtual memory area being deleted.
*/
if (Entry != Entry1)
{
DPRINT1("Someone changed ppte entry while we slept\n");
- KeBugCheck(MEMORY_MANAGEMENT);
+ KeBugCheck(MEMORY_MANAGEMENT);
}
/*
#ifndef NEWCC
Status = CcRosUnmapCacheSegment(Bcb, FileOffset, FALSE);
#else
- Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
#endif
if (!NT_SUCCESS(Status))
{
DPRINT("MmUnmapViewInSystemSpace() called\n");
AddressSpace = MmGetKernelAddressSpace();
-
+
MmLockAddressSpace(AddressSpace);
Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
-
+
MmUnlockAddressSpace(AddressSpace);
return Status;