return RVA(AllocatedBase, PAGE_SIZE);
}
-VOID
-MiFreeStackPage(PVOID Context,
- MEMORY_AREA* MemoryArea,
- PVOID Address,
- PFN_TYPE Page,
- SWAPENTRY SwapEntry,
- BOOLEAN Dirty)
-{
- ASSERT(SwapEntry == 0);
- if (Page) MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
-}
-
-VOID
-NTAPI
-MmDeleteKernelStack(PVOID StackBase,
- BOOLEAN GuiStack)
-{
- ULONG StackSize = GuiStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE;
-
- /* Lock the Address Space */
- MmLockAddressSpace(MmGetKernelAddressSpace());
-
- /* Delete the Stack */
- MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
- (PVOID)((ULONG_PTR)StackBase - StackSize),
- MiFreeStackPage,
- NULL);
-
- /* Unlock the Address Space */
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
-}
-
VOID
NTAPI
MmDeleteTeb(PEPROCESS Process,
MmUnlockAddressSpace(ProcessAddressSpace);
}
-PVOID
-NTAPI
-MmCreateKernelStack(BOOLEAN GuiStack,
- UCHAR Node)
-{
- PMEMORY_AREA StackArea;
- ULONG i;
- PHYSICAL_ADDRESS BoundaryAddressMultiple;
- ULONG StackSize = GuiStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE;
- PFN_TYPE Page[KERNEL_LARGE_STACK_SIZE / PAGE_SIZE];
- PVOID KernelStack = NULL;
- NTSTATUS Status;
-
- /* Initialize the Boundary Address */
- BoundaryAddressMultiple.QuadPart = 0;
-
- /* Lock the Kernel Address Space */
- MmLockAddressSpace(MmGetKernelAddressSpace());
-
- /* Create a MAREA for the Kernel Stack */
- Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
- MEMORY_AREA_KERNEL_STACK,
- &KernelStack,
- StackSize,
- PAGE_READWRITE,
- &StackArea,
- FALSE,
- 0,
- BoundaryAddressMultiple);
-
- /* Unlock the Address Space */
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
-
- /* Check for Success */
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create thread stack\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /*
- * 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]);
- }
-
- /* Create a Virtual Mapping for it */
- Status = MmCreateVirtualMapping(NULL,
- KernelStack,
- PAGE_READWRITE,
- Page,
- StackSize / PAGE_SIZE);
-
- /* Check for success */
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Could not create Virtual Mapping for Kernel Stack\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /* Return the stack base */
- return (PVOID)((ULONG_PTR)KernelStack +
- (GuiStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE));
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-MmGrowKernelStack(PVOID StackPointer)
-{
- PETHREAD Thread = PsGetCurrentThread();
-
- /* Make sure the stack did not overflow */
- ASSERT(((PCHAR)Thread->Tcb.StackBase - (PCHAR)Thread->Tcb.StackLimit) <=
- (KERNEL_LARGE_STACK_SIZE + PAGE_SIZE));
-
- /* Check if we have reserved space for our grow */
- if ((PCHAR)Thread->Tcb.StackBase - (PCHAR)Thread->Tcb.StackLimit +
- KERNEL_STACK_SIZE > KERNEL_LARGE_STACK_SIZE)
- {
- return STATUS_STACK_OVERFLOW;
- }
-
- /*
- * 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 */
- return STATUS_SUCCESS;
-}
-
NTSTATUS
NTAPI
MmCreatePeb(PEPROCESS Process)