extern ULONG NtOSCSDVersion;
extern ULONG NtGlobalFlag;
+#define MM_HIGHEST_VAD_ADDRESS \
+ (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
+
/* FUNCTIONS *****************************************************************/
PVOID
*/
do {
DPRINT("Trying to allocate: %x\n", AllocatedBase);
- Status = MmCreateMemoryArea(Process,
- ProcessAddressSpace,
+ Status = MmCreateMemoryArea(ProcessAddressSpace,
MEMORY_AREA_PEB_OR_TEB,
&AllocatedBase,
PAGE_SIZE,
PAGE_READWRITE,
&MemoryArea,
TRUE,
- FALSE,
+ 0,
BoundaryAddressMultiple);
AllocatedBase = RVA(AllocatedBase, -PAGE_SIZE);
} while (Status != STATUS_SUCCESS);
/* Initialize the Region */
- MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ MmInitializeRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
PAGE_SIZE,
MEM_COMMIT,
PAGE_READWRITE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
-VOID
-MiFreePebPage(PVOID Context,
- MEMORY_AREA* MemoryArea,
- PVOID Address,
- PFN_TYPE Page,
- SWAPENTRY SwapEntry,
- BOOLEAN Dirty)
-{
- PEPROCESS Process = (PEPROCESS)Context;
-
- if (Page != 0)
- {
- SWAPENTRY SavedSwapEntry;
- SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
- if (SavedSwapEntry != 0)
- {
- MmFreeSwapPage(SavedSwapEntry);
- MmSetSavedSwapEntryPage(Page, 0);
- }
- MmDeleteRmap(Page, Process, Address);
- MmReleasePageMemoryConsumer(MC_USER, Page);
- }
- else if (SwapEntry != 0)
- {
- MmFreeSwapPage(SwapEntry);
- }
-}
-
VOID
STDCALL
MmDeleteTeb(PEPROCESS Process,
PTEB Teb)
{
PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace;
+ PMEMORY_AREA MemoryArea;
/* Lock the Address Space */
MmLockAddressSpace(ProcessAddressSpace);
-
- /* Delete the Stack */
- MmFreeMemoryAreaByPtr(ProcessAddressSpace,
- Teb,
- MiFreePebPage,
- Process);
+
+ MemoryArea = MmLocateMemoryAreaByAddress(ProcessAddressSpace, (PVOID)Teb);
+ if (MemoryArea)
+ {
+ /* Delete the Teb */
+ MmFreeVirtualMemory(Process, MemoryArea);
+ }
/* Unlock the Address Space */
MmUnlockAddressSpace(ProcessAddressSpace);
PMEMORY_AREA StackArea;
ULONG i;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
- PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE];
+ ULONG StackSize = GuiStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE;
+ PFN_TYPE Page[KERNEL_LARGE_STACK_SIZE / PAGE_SIZE];
PVOID KernelStack = NULL;
NTSTATUS Status;
MmLockAddressSpace(MmGetKernelAddressSpace());
/* Create a MAREA for the Kernel Stack */
- Status = MmCreateMemoryArea(NULL,
- MmGetKernelAddressSpace(),
+ Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
MEMORY_AREA_KERNEL_STACK,
&KernelStack,
- MM_STACK_SIZE,
- 0,
+ StackSize,
+ PAGE_READWRITE,
&StackArea,
FALSE,
- FALSE,
+ 0,
BoundaryAddressMultiple);
/* Unlock the Address Space */
KEBUGCHECK(0);
}
- /* Mark the Stack in use */
- for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
+ /*
+ * Mark the Stack in use.
+ * Note: Currently we mark all 60KB in use for a GUI Thread.
+ * We should only do this inside MmGrowKernelStack. TODO!
+ */
+ for (i = 0; i < (StackSize / PAGE_SIZE); i++)
{
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
}
KernelStack,
PAGE_READWRITE,
Page,
- MM_STACK_SIZE / PAGE_SIZE);
+ StackSize / PAGE_SIZE);
/* Check for success */
if (!NT_SUCCESS(Status))
KEBUGCHECK(0);
}
+ /* Return the stack */
return KernelStack;
}
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+MmGrowKernelStack(PVOID StackPointer)
+{
+ PETHREAD Thread = PsGetCurrentThread();
+
+ /* Make sure we have reserved space for our grow */
+ ASSERT(((PCHAR)Thread->Tcb.StackBase - (PCHAR)Thread->Tcb.StackLimit) <=
+ (KERNEL_LARGE_STACK_SIZE + PAGE_SIZE));
+
+ /*
+ * We'll give you three more pages.
+ * NOTE: See note in MmCreateKernelStack. These pages are already being reserved.
+ * It would be more efficient to only grow them (commit them) here.
+ */
+ Thread->Tcb.StackLimit -= KERNEL_STACK_SIZE;
+
+ /* Return success */
+ DPRINT1("Thread, Thread Limit, Stack %p %p %p\n", KeGetCurrentThread(),
+ KeGetCurrentThread()->StackLimit,
+ StackPointer);
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
STDCALL
MmCreatePeb(PEPROCESS Process)
{
PPEB Peb = NULL;
LARGE_INTEGER SectionOffset;
- ULONG ViewSize = 0;
+ SIZE_T ViewSize = 0;
PVOID TableBase = NULL;
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
NTSTATUS Status;
KAFFINITY ProcessAffinityMask = 0;
SectionOffset.QuadPart = (ULONGLONG)0;
-
DPRINT("MmCreatePeb\n");
+ /* Allocate the PEB */
+ Peb = MiCreatePebOrTeb(Process,
+ (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
+ ASSERT(Peb == (PVOID)0x7FFDF000);
+
/* Map NLS Tables */
DPRINT("Mapping NLS\n");
Status = MmMapViewOfSection(NlsSectionObject,
/* Attach to Process */
KeAttachProcess(&Process->Pcb);
- /* Allocate the PEB */
- Peb = MiCreatePebOrTeb(Process, (PVOID)PEB_BASE);
-
/* Initialize the PEB */
DPRINT("Allocated: %x\n", Peb);
RtlZeroMemory(Peb, sizeof(PEB));
}
/* Allocate the TEB */
- Teb = MiCreatePebOrTeb(Process, (PVOID)TEB_BASE);
+ Teb = MiCreatePebOrTeb(Process,
+ (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
/* Initialize the PEB */
RtlZeroMemory(Teb, sizeof(TEB));
PVOID BaseAddress;
PMEMORY_AREA MemoryArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
- ULONG ViewSize = 0;
+ SIZE_T ViewSize = 0;
PVOID ImageBase = 0;
BoundaryAddressMultiple.QuadPart = 0;
/* Protect the highest 64KB of the process address space */
BaseAddress = (PVOID)MmUserProbeAddress;
- Status = MmCreateMemoryArea(Process,
- ProcessAddressSpace,
+ Status = MmCreateMemoryArea(ProcessAddressSpace,
MEMORY_AREA_NO_ACCESS,
&BaseAddress,
0x10000,
PAGE_NOACCESS,
&MemoryArea,
FALSE,
- FALSE,
+ 0,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
/* Protect the 60KB above the shared user page */
BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
- Status = MmCreateMemoryArea(Process,
- ProcessAddressSpace,
+ Status = MmCreateMemoryArea(ProcessAddressSpace,
MEMORY_AREA_NO_ACCESS,
&BaseAddress,
0x10000 - PAGE_SIZE,
PAGE_NOACCESS,
&MemoryArea,
FALSE,
- FALSE,
+ 0,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
/* Create the shared data page */
BaseAddress = (PVOID)USER_SHARED_DATA;
- Status = MmCreateMemoryArea(Process,
- ProcessAddressSpace,
+ Status = MmCreateMemoryArea(ProcessAddressSpace,
MEMORY_AREA_SHARED_DATA,
&BaseAddress,
PAGE_SIZE,
- PAGE_READONLY,
+ PAGE_EXECUTE_READ,
&MemoryArea,
FALSE,
- FALSE,
+ 0,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to map process Image\n");
- ObDereferenceObject(Section);
- goto exit;
+ return Status;
}
- ObDereferenceObject(Section);
/* Save the pointer */
Process->SectionBaseAddress = ImageBase;