mirror of
https://github.com/reactos/reactos.git
synced 2025-04-18 03:34:11 +00:00
Forgot this
svn path=/trunk/; revision=14661
This commit is contained in:
parent
7740536c18
commit
781c6b374f
1 changed files with 373 additions and 0 deletions
373
reactos/ntoskrnl/mm/process.c
Normal file
373
reactos/ntoskrnl/mm/process.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue