diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 43ebc3689f0..c38e7742698 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: view.c,v 1.58 2003/02/18 22:06:53 chorns Exp $ +/* $Id: view.c,v 1.59 2003/05/17 15:27:34 ekohl Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/cc/view.c @@ -543,6 +543,7 @@ CcRosCreateCacheSegment(PBCB Bcb, Bcb->CacheSegmentSize, PAGE_READWRITE, (PMEMORY_AREA*)¤t->MemoryArea, + FALSE, FALSE); MmUnlockAddressSpace(MmGetKernelAddressSpace()); if (!NT_SUCCESS(Status)) diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index dc5ca209ca7..138398418dd 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -126,7 +126,7 @@ typedef struct union { struct - { + { SECTION_OBJECT* Section; ULONG ViewOffset; LIST_ENTRY ViewListEntry; @@ -169,7 +169,8 @@ NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process, ULONG Length, ULONG Attributes, MEMORY_AREA** Result, - BOOL FixedAddress); + BOOL FixedAddress, + BOOL TopDown); MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace, PVOID Address); NTSTATUS MmInitMemoryAreas(VOID); @@ -289,7 +290,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace, PVOID Address, ULONG Length); -PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length); +PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown); VOID ExUnmapPage(PVOID Addr); PVOID ExAllocatePage(VOID); diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index ba1007586e3..a4806771f35 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: kthread.c,v 1.36 2003/04/06 10:45:16 chorns Exp $ +/* $Id: kthread.c,v 1.37 2003/05/17 15:28:06 ekohl Exp $ * * FILE: ntoskrnl/ke/kthread.c * PURPOSE: Microkernel thread support @@ -106,6 +106,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First) MM_STACK_SIZE, 0, &StackArea, + FALSE, FALSE); MmUnlockAddressSpace(MmGetKernelAddressSpace()); diff --git a/reactos/ntoskrnl/mm/anonmem.c b/reactos/ntoskrnl/mm/anonmem.c index b9a7005ab7d..babac7e1098 100644 --- a/reactos/ntoskrnl/mm/anonmem.c +++ b/reactos/ntoskrnl/mm/anonmem.c @@ -16,14 +16,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: anonmem.c,v 1.12 2003/04/28 10:37:39 gvg Exp $ +/* $Id: anonmem.c,v 1.13 2003/05/17 15:28:58 ekohl Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/anonmem.c * PURPOSE: Implementing anonymous memory. * PROGRAMMER: David Welch */ - + /* INCLUDE *****************************************************************/ #include @@ -624,8 +624,8 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, RegionSize, Protect, &MemoryArea, - PBaseAddress != 0); - + PBaseAddress != 0, + (AllocationType & MEM_TOP_DOWN)); if (!NT_SUCCESS(Status)) { MmUnlockAddressSpace(AddressSpace); diff --git a/reactos/ntoskrnl/mm/cont.c b/reactos/ntoskrnl/mm/cont.c index 339556d643f..6df76509b75 100644 --- a/reactos/ntoskrnl/mm/cont.c +++ b/reactos/ntoskrnl/mm/cont.c @@ -1,4 +1,4 @@ -/* $Id: cont.c,v 1.25 2002/11/05 20:35:33 hbirr Exp $ +/* $Id: cont.c,v 1.26 2003/05/17 15:28:58 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -50,6 +50,7 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes, NumberOfBytes, 0, &MArea, + FALSE, FALSE); MmUnlockAddressSpace(MmGetKernelAddressSpace()); diff --git a/reactos/ntoskrnl/mm/iospace.c b/reactos/ntoskrnl/mm/iospace.c index 0ce9fba44a5..e5d0fffccf4 100644 --- a/reactos/ntoskrnl/mm/iospace.c +++ b/reactos/ntoskrnl/mm/iospace.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: iospace.c,v 1.17 2002/11/05 20:35:33 hbirr Exp $ +/* $Id: iospace.c,v 1.18 2003/05/17 15:28:58 ekohl Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/iospace.c @@ -84,6 +84,7 @@ MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress, NumberOfBytes, 0, &marea, + FALSE, FALSE); MmUnlockAddressSpace(MmGetKernelAddressSpace()); diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index d6dfe50cf4a..5513373e5e6 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * Copyright (C) 1998, 1999, 2000, 2001, 2003 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -188,12 +188,12 @@ static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace, current_entry->Flink = inserted_entry; inserted_entry->Flink=ListHead; inserted_entry->Blink=current_entry; - ListHead->Blink = inserted_entry; + ListHead->Blink = inserted_entry; return; } if (current->BaseAddress < marea->BaseAddress && next->BaseAddress > marea->BaseAddress) - { + { inserted_entry->Flink = current_entry->Flink; inserted_entry->Blink = current_entry; inserted_entry->Flink->Blink = inserted_entry; @@ -205,7 +205,8 @@ static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace, InsertTailList(ListHead,inserted_entry); } -PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length) + +PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length) { PLIST_ENTRY ListHead; PLIST_ENTRY current_entry; @@ -214,7 +215,7 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length) ULONG Gap; PVOID Address; - DPRINT("MmFindGap(Length %x)\n",Length); + DPRINT("MmFindGapBottomUp(Length %x)\n",Length); ListHead = &AddressSpace->MAreaListHead; @@ -258,6 +259,94 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length) return Address; } + +PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length) +{ + PLIST_ENTRY ListHead; + PLIST_ENTRY current_entry; + MEMORY_AREA* current; + ULONG Gap; + PVOID Address; + PVOID TopAddress; + PVOID BottomAddress; + PVOID HighestAddress; + + DPRINT("MmFindGapTopDown(Length %lx)\n",Length); + + if (AddressSpace->LowestAddress < KERNEL_BASE) + { + HighestAddress = (PVOID)0x7FFE0000; /* Start below the PEB */ + } + else + { + HighestAddress = (PVOID)0xFFFFFFFF; + } + + TopAddress = HighestAddress; + + ListHead = &AddressSpace->MAreaListHead; + current_entry = ListHead->Blink; + while (current_entry->Blink != ListHead) + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + BottomAddress = current->BaseAddress + PAGE_ROUND_UP(current->Length); + DPRINT("Base %p Length %lx\n", current->BaseAddress, PAGE_ROUND_UP(current->Length)); + + if (BottomAddress < HighestAddress) + { + Gap = TopAddress - BottomAddress; + DPRINT("Bottom %p Top %p Gap %lx\n", BottomAddress, TopAddress, Gap); + if (Gap >= Length) + { + DPRINT1("Found gap at %p\n", TopAddress - Length); + return(TopAddress - Length); + } + TopAddress = current->BaseAddress; + } + current_entry = current_entry->Blink; + } + + if (current_entry == ListHead) + { + Address = (PVOID)HighestAddress - Length; + } + else + { + Address = TopAddress - Length; + } + + /* Check if enough space for the block */ + if (AddressSpace->LowestAddress < KERNEL_BASE) + { + if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) + { + DPRINT("Failed to find gap\n"); + return NULL; + } + } + else + { + if (Length >= 0xFFFFFFFF - (ULONG)Address) + { + DPRINT("Failed to find gap\n"); + return NULL; + } + } + + DPRINT("Found gap at %p\n", Address); + return Address; +} + + +PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown) +{ + if (TopDown) + return MmFindGapTopDown(AddressSpace, Length); + + return MmFindGapBottomUp(AddressSpace, Length); +} + + NTSTATUS MmInitMemoryAreas(VOID) /* * FUNCTION: Initialize the memory area list @@ -286,7 +375,7 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace, MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress); if (MemoryArea == NULL) - { + { KeBugCheck(0); return(STATUS_UNSUCCESSFUL); } @@ -381,7 +470,8 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process, ULONG Length, ULONG Attributes, MEMORY_AREA** Result, - BOOL FixedAddress) + BOOL FixedAddress, + BOOL TopDown) /* * FUNCTION: Create a memory area * ARGUMENTS: @@ -400,12 +490,13 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process, "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", Type,BaseAddress,*BaseAddress,Length,Attributes,Result); - if ((*BaseAddress)==0 && !FixedAddress) + if ((*BaseAddress) == 0 && !FixedAddress) { - tmpLength = PAGE_ROUND_UP(Length); + tmpLength = PAGE_ROUND_UP(Length); *BaseAddress = MmFindGap(AddressSpace, - PAGE_ROUND_UP(Length) +(PAGE_SIZE*2)); - if ((*BaseAddress)==0) + PAGE_ROUND_UP(Length) +(PAGE_SIZE*2), + TopDown); + if ((*BaseAddress) == 0) { DPRINT("No suitable gap\n"); return(STATUS_NO_MEMORY); @@ -413,9 +504,9 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process, (*BaseAddress)=(*BaseAddress)+PAGE_SIZE; } else - { + { tmpLength = (ULONG)*BaseAddress + Length - PAGE_ROUND_DOWN((*BaseAddress)); - (*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress)); + (*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress)); if (MmOpenMemoryAreaByRegion(AddressSpace, *BaseAddress, tmpLength)!=NULL) diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index b6891ca6530..87577e81e74 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -1,4 +1,4 @@ -/* $Id: mdl.c,v 1.47 2002/11/10 18:17:42 chorns Exp $ +/* $Id: mdl.c,v 1.48 2003/05/17 15:28:58 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -51,6 +51,7 @@ MmInitializeMdlImplementation(VOID) MI_MDL_MAPPING_REGION_SIZE, 0, &Result, + FALSE, FALSE); if (!NT_SUCCESS(Status)) { diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 82cf9197bc1..d6b671a593f 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -1,4 +1,4 @@ -/* $Id: mminit.c,v 1.44 2003/05/17 13:45:04 hbirr Exp $ +/* $Id: mminit.c,v 1.45 2003/05/17 15:28:58 ekohl Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -106,6 +106,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress, Length, 0, &kernel_text_desc, + FALSE, FALSE); Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) - @@ -120,24 +121,26 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress, * the only thread running. */ MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), + MmGetKernelAddressSpace(), MEMORY_AREA_SYSTEM, &BaseAddress, Length, 0, &kernel_data_desc, + FALSE, FALSE); BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__)); // Length = ParamLength; Length = LastKernelAddress - (ULONG)BaseAddress; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), + MmGetKernelAddressSpace(), MEMORY_AREA_SYSTEM, &BaseAddress, Length, 0, &kernel_param_desc, + FALSE, FALSE); BaseAddress = (PVOID)(LastKernelAddress + PAGE_SIZE); @@ -149,6 +152,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress, Length, 0, &kernel_pool_desc, + FALSE, FALSE); MmPagedPoolSize = MM_PAGED_POOL_SIZE; @@ -163,6 +167,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress, Length, 0, &MiPagedPoolDescriptor, + FALSE, FALSE); MmInitializePagedPool(); @@ -178,6 +183,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress, Length, 0, &kernel_shared_data_desc, + FALSE, FALSE); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &MmSharedDataPagePhysicalAddress); diff --git a/reactos/ntoskrnl/mm/ncache.c b/reactos/ntoskrnl/mm/ncache.c index d6ceb34db8f..71bbf33ab3d 100644 --- a/reactos/ntoskrnl/mm/ncache.c +++ b/reactos/ntoskrnl/mm/ncache.c @@ -1,4 +1,4 @@ -/* $Id: ncache.c,v 1.23 2002/11/05 20:35:33 hbirr Exp $ +/* $Id: ncache.c,v 1.24 2003/05/17 15:28:58 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -62,6 +62,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes) NumberOfBytes, 0, &marea, + FALSE, FALSE); MmUnlockAddressSpace(MmGetKernelAddressSpace()); diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 4e2e77324f7..73a0987c9a9 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: section.c,v 1.112 2003/05/17 13:43:44 hbirr Exp $ +/* $Id: section.c,v 1.113 2003/05/17 15:28:58 ekohl Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/section.c @@ -2790,7 +2790,8 @@ MmMapViewOfSegment(PEPROCESS Process, PVOID* BaseAddress, ULONG ViewSize, ULONG Protect, - ULONG ViewOffset) + ULONG ViewOffset, + BOOL TopDown) { PMEMORY_AREA MArea; NTSTATUS Status; @@ -2803,7 +2804,8 @@ MmMapViewOfSegment(PEPROCESS Process, ViewSize, Protect, &MArea, - FALSE); + FALSE, + TopDown); if (!NT_SUCCESS(Status)) { DPRINT1("Mapping between 0x%.8X and 0x%.8X failed.\n", @@ -3280,6 +3282,7 @@ MmAllocateSection (IN ULONG Length) Length, 0, &marea, + FALSE, FALSE); if (!NT_SUCCESS(Status)) { @@ -3305,7 +3308,7 @@ MmAllocateSection (IN ULONG Length) TRUE); if (!NT_SUCCESS(Status)) { - DbgPrint("Unable to create virtual mapping\n"); + DbgPrint("Unable to create virtual mapping\n"); KeBugCheck(0); } } @@ -3420,7 +3423,7 @@ MmMapViewOfSection(IN PVOID SectionObject, return(STATUS_UNSUCCESSFUL); } /* Otherwise find a gap to map the image. */ - ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize)); + ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), FALSE); if (ImageBase == NULL) { MmUnlockSection(Section); @@ -3446,7 +3449,8 @@ MmMapViewOfSection(IN PVOID SectionObject, &SBaseAddress, Section->Segments[i].Length, Section->Segments[i].Protection, - Section->Segments[i].FileOffset); + Section->Segments[i].FileOffset, + FALSE); MmUnlockSectionSegment(&Section->Segments[i]); if (!NT_SUCCESS(Status)) { @@ -3521,7 +3525,8 @@ MmMapViewOfSection(IN PVOID SectionObject, BaseAddress, *ViewSize, Protect, - ViewOffset); + ViewOffset, + (AllocationType & MEM_TOP_DOWN)); MmUnlockSectionSegment(Section->Segments); MmUnlockAddressSpace(AddressSpace); if (!NT_SUCCESS(Status)) @@ -3618,7 +3623,8 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, MappedBase, *ViewSize, PAGE_READWRITE, - 0); + 0, + FALSE); MmUnlockSectionSegment(Section->Segments); MmUnlockAddressSpace(AddressSpace); diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 786cf9da1b6..1fe76664a3f 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.99 2003/05/16 17:37:17 ekohl Exp $ +/* $Id: process.c,v 1.100 2003/05/17 15:29:50 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -586,9 +586,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, * Now we have created the process proper */ - /* - * Create the shared data page - */ + /* Create the shared data page */ MmLockAddressSpace(&Process->AddressSpace); BaseAddress = (PVOID)USER_SHARED_DATA; Status = MmCreateMemoryArea(Process, @@ -598,6 +596,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, PAGE_SIZE, PAGE_READONLY, &MemoryArea, + FALSE, FALSE); MmUnlockAddressSpace(&Process->AddressSpace); if (!NT_SUCCESS(Status)) @@ -605,7 +604,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, DPRINT1("Failed to create shared data page\n"); KeBugCheck(0); } - + /* * Map ntdll */ diff --git a/reactos/ntoskrnl/ps/w32call.c b/reactos/ntoskrnl/ps/w32call.c index eb970cbe8ea..8ed7e97dc6d 100644 --- a/reactos/ntoskrnl/ps/w32call.c +++ b/reactos/ntoskrnl/ps/w32call.c @@ -1,4 +1,4 @@ -/* $Id: w32call.c,v 1.5 2002/10/01 19:27:25 chorns Exp $ +/* $Id: w32call.c,v 1.6 2003/05/17 15:29:50 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -162,8 +162,9 @@ PsAllocateCallbackStack(ULONG StackSize) StackSize, 0, &StackArea, + FALSE, FALSE); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); if (!NT_SUCCESS(Status)) { DPRINT("Failed to create thread stack\n");