Forgot this

svn path=/trunk/; revision=14661
This commit is contained in:
Alex Ionescu 2005-04-18 02:11:19 +00:00
parent 7740536c18
commit 781c6b374f

View file

@ -0,0 +1,373 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/process.c
* PURPOSE: Memory functions related to Processes
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
extern ULONG NtMajorVersion;
extern ULONG NtMinorVersion;
extern ULONG NtOSCSDVersion;
/* FUNCTIONS *****************************************************************/
PVOID
STDCALL
MiCreatePebOrTeb(PEPROCESS Process,
PVOID BaseAddress)
{
NTSTATUS Status;
PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace;
PMEMORY_AREA MemoryArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
BoundaryAddressMultiple.QuadPart = 0;
/* Acquire the Lock */
MmLockAddressSpace(ProcessAddressSpace);
/* Create a Peb or Teb */
Status = MmCreateMemoryArea(Process,
ProcessAddressSpace,
MEMORY_AREA_PEB_OR_TEB,
&BaseAddress,
PAGE_SIZE,
PAGE_READWRITE,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to allocate PEB or TEB\n");
}
/* Initialize the Region */
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
PAGE_SIZE,
MEM_COMMIT,
PAGE_READWRITE);
/* Reserve the pages */
MmReserveSwapPages(PAGE_SIZE);
/* Unlock Address Space */
DPRINT("Returning\n");
MmUnlockAddressSpace(ProcessAddressSpace);
return BaseAddress;
}
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
STDCALL
MmDeleteKernelStack(PVOID Stack,
BOOLEAN GuiStack)
{
/* Lock the Address Space */
MmLockAddressSpace(MmGetKernelAddressSpace());
/* Delete the Stack */
MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
Stack,
MiFreeStackPage,
NULL);
/* Unlock the Address Space */
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
PVOID
STDCALL
MmCreateKernelStack(BOOLEAN GuiStack)
{
PMEMORY_AREA StackArea;
ULONG i;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PFN_TYPE Page[MM_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(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_KERNEL_STACK,
&KernelStack,
MM_STACK_SIZE,
0,
&StackArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
/* Unlock the Address Space */
MmUnlockAddressSpace(MmGetKernelAddressSpace());
/* Check for Success */
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create thread stack\n");
KEBUGCHECK(0);
}
/* Mark the Stack in use */
for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
{
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
}
/* Create a Virtual Mapping for it */
Status = MmCreateVirtualMapping(NULL,
KernelStack,
PAGE_READWRITE,
Page,
MM_STACK_SIZE / PAGE_SIZE);
/* Check for success */
if (!NT_SUCCESS(Status))
{
DPRINT1("Could not create Virtual Mapping for Kernel Stack\n");
KEBUGCHECK(0);
}
return KernelStack;
}
NTSTATUS
STDCALL
MmCreatePeb(PEPROCESS Process)
{
PPEB Peb = NULL;
LARGE_INTEGER SectionOffset;
ULONG ViewSize = 0;
PVOID TableBase = NULL;
NTSTATUS Status;
SectionOffset.QuadPart = (ULONGLONG)0;
DPRINT("MmCreatePeb\n");
/* Map NLS Tables */
DPRINT("Mapping NLS\n");
Status = MmMapViewOfSection(NlsSectionObject,
Process,
&TableBase,
0,
0,
&SectionOffset,
&ViewSize,
ViewShare,
MEM_TOP_DOWN,
PAGE_READONLY);
if (!NT_SUCCESS(Status))
{
DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
return(Status);
}
DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize);
/* 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));
/* Set up data */
DPRINT("Setting up PEB\n");
Peb->ImageBaseAddress = Process->SectionBaseAddress;
Peb->OSMajorVersion = NtMajorVersion;
Peb->OSMinorVersion = NtMinorVersion;
Peb->OSBuildNumber = 2195;
Peb->OSPlatformId = 2; //VER_PLATFORM_WIN32_NT;
Peb->OSCSDVersion = NtOSCSDVersion;
Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset;
Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset;
Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset;
Peb->NumberOfProcessors = KeNumberProcessors;
Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE);
Process->Peb = Peb;
KeDetachProcess();
DPRINT("MmCreatePeb: Peb created at %p\n", Peb);
return STATUS_SUCCESS;
}
VOID
STDCALL
MmCreateTeb(VOID)
{
}
NTSTATUS
STDCALL
MmCreateProcessAddressSpace(IN PEPROCESS Process,
IN PSECTION_OBJECT Section OPTIONAL)
{
NTSTATUS Status;
PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace;
PVOID BaseAddress;
PMEMORY_AREA MemoryArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
BoundaryAddressMultiple.QuadPart = 0;
ULONG ViewSize = 0;
PVOID ImageBase = 0;
/* Initialize the Addresss Space */
MmInitializeAddressSpace(Process, ProcessAddressSpace);
/* Acquire the Lock */
MmLockAddressSpace(ProcessAddressSpace);
/* Protect the highest 64KB of the process address space */
BaseAddress = (PVOID)MmUserProbeAddress;
Status = MmCreateMemoryArea(Process,
ProcessAddressSpace,
MEMORY_AREA_NO_ACCESS,
&BaseAddress,
0x10000,
PAGE_NOACCESS,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to protect last 64KB\n");
goto exit;
}
/* Protect the 60KB above the shared user page */
BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
Status = MmCreateMemoryArea(Process,
ProcessAddressSpace,
MEMORY_AREA_NO_ACCESS,
&BaseAddress,
0x10000 - PAGE_SIZE,
PAGE_NOACCESS,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to protect the memory above the shared user page\n");
goto exit;
}
/* Create the shared data page */
BaseAddress = (PVOID)USER_SHARED_DATA;
Status = MmCreateMemoryArea(Process,
ProcessAddressSpace,
MEMORY_AREA_SHARED_DATA,
&BaseAddress,
PAGE_SIZE,
PAGE_READONLY,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create Shared User Data\n");
goto exit;
}
/* Check if there's a Section Object */
if (Section)
{
UNICODE_STRING FileName;
PWCHAR szSrc;
PCHAR szDest;
USHORT lnFName = 0;
/* Unlock the Address Space */
DPRINT("Unlocking\n");
MmUnlockAddressSpace(ProcessAddressSpace);
DPRINT("Mapping process image. Section: %p, Process: %p, ImageBase: %p\n",
Section, Process, &ImageBase);
Status = MmMapViewOfSection(Section,
Process,
(PVOID*)&ImageBase,
0,
0,
NULL,
&ViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to map process Image\n");
ObDereferenceObject(Section);
goto exit;
}
ObDereferenceObject(Section);
/* Save the pointer */
Process->SectionBaseAddress = ImageBase;
/* Determine the image file name and save it to EPROCESS */
DPRINT("Getting Image name\n");
FileName = Section->FileObject->FileName;
szSrc = (PWCHAR)(FileName.Buffer + (FileName.Length / sizeof(WCHAR)) - 1);
while(szSrc >= FileName.Buffer)
{
if(*szSrc == L'\\')
{
szSrc++;
break;
}
else
{
szSrc--;
lnFName++;
}
}
/* Copy the to the process and truncate it to 15 characters if necessary */
DPRINT("Copying and truncating\n");
szDest = Process->ImageFileName;
lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1);
while(lnFName-- > 0) *(szDest++) = (UCHAR)*(szSrc++);
/* Return status to caller */
return Status;
}
exit:
/* Unlock the Address Space */
DPRINT("Unlocking\n");
MmUnlockAddressSpace(ProcessAddressSpace);
/* Return status to caller */
return Status;
}