Forgot this Added: trunk/reactos/ntoskrnl/mm/process.c _____
Added: trunk/reactos/ntoskrnl/mm/process.c --- trunk/reactos/ntoskrnl/mm/process.c 2005-04-18 00:42:31 UTC (rev 14660) +++ trunk/reactos/ntoskrnl/mm/process.c 2005-04-18 02:11:19 UTC (rev 14661) @@ -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; +}