Author: akorotaev Date: Sat Jan 5 15:15:43 2008 New Revision: 31605
URL: http://svn.reactos.org/svn/reactos?rev=31605&view=rev Log: Forgot to rename these files
Added: branches/cache_manager_rewrite/mm/mdlsup.c - copied unchanged from r31604, branches/cache_manager_rewrite/mm/mdl.c branches/cache_manager_rewrite/mm/procsup.c - copied unchanged from r31604, branches/cache_manager_rewrite/mm/process.c Removed: branches/cache_manager_rewrite/mm/mdl.c branches/cache_manager_rewrite/mm/process.c
Removed: branches/cache_manager_rewrite/mm/mdl.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/mdl.c?r... ============================================================================== --- branches/cache_manager_rewrite/mm/mdl.c (original) +++ branches/cache_manager_rewrite/mm/mdl.c (removed) @@ -1,967 +1,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/mm/mdl.c - * PURPOSE: Manipulates MDLs - * - * PROGRAMMERS: David Welch (welch@cwcom.net) - */ - -/* INCLUDES ****************************************************************/ - -#include <ntoskrnl.h> -#define NDEBUG -#include <internal/debug.h> - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, MmInitializeMdlImplementation) -#endif - -/* GLOBALS *******************************************************************/ - -#define TAG_MDL TAG('M', 'D', 'L', ' ') - -#define MI_MDL_MAPPING_REGION_SIZE (256*1024*1024) - -static PVOID MiMdlMappingRegionBase = NULL; -static RTL_BITMAP MiMdlMappingRegionAllocMap; -static ULONG MiMdlMappingRegionHint; -static KSPIN_LOCK MiMdlMappingRegionLock; -extern ULONG MmPageArraySize; - -/* -MDL Flags desc. - -MDL_PAGES_LOCKED MmProbeAndLockPages has been called for this mdl -MDL_SOURCE_IS_NONPAGED_POOL mdl has been build by MmBuildMdlForNonPagedPool -MDL_PARTIAL mdl has been built by IoBuildPartialMdl -MDL_MAPPING_CAN_FAIL in case of an error, MmMapLockedPages will return NULL instead of to bugcheck -MDL_MAPPED_TO_SYSTEM_VA mdl has been mapped into kernel space using MmMapLockedPages -MDL_PARTIAL_HAS_BEEN_MAPPED mdl flagged MDL_PARTIAL has been mapped into kernel space using MmMapLockedPages -*/ - -/* FUNCTIONS *****************************************************************/ - - -/* - * @unimplemented - */ -NTSTATUS -STDCALL -MmAdvanceMdl ( - IN PMDL Mdl, - IN ULONG NumberOfBytes - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - -VOID -INIT_FUNCTION -NTAPI -MmInitializeMdlImplementation(VOID) -{ - MEMORY_AREA* Result; - NTSTATUS Status; - PVOID Buffer; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - - BoundaryAddressMultiple.QuadPart = 0; - MiMdlMappingRegionHint = 0; - MiMdlMappingRegionBase = NULL; - - MmLockAddressSpace(MmGetKernelAddressSpace()); - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_MDL_MAPPING, - &MiMdlMappingRegionBase, - MI_MDL_MAPPING_REGION_SIZE, - PAGE_READWRITE, - &Result, - FALSE, - 0, - BoundaryAddressMultiple); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - KEBUGCHECK(0); - } - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - - Buffer = ExAllocatePoolWithTag(NonPagedPool, - MI_MDL_MAPPING_REGION_SIZE / (PAGE_SIZE * 8), - TAG_MDL); - - RtlInitializeBitMap(&MiMdlMappingRegionAllocMap, Buffer, MI_MDL_MAPPING_REGION_SIZE / PAGE_SIZE); - RtlClearAllBits(&MiMdlMappingRegionAllocMap); - - KeInitializeSpinLock(&MiMdlMappingRegionLock); -} - - -PVOID -NTAPI -MmGetMdlPageAddress(PMDL Mdl, PVOID Offset) -{ - PPFN_NUMBER MdlPages; - - MdlPages = (PPFN_NUMBER)(Mdl + 1); - - return((PVOID)MdlPages[((ULONG_PTR)Offset) / PAGE_SIZE]); -} - - -/* - * @implemented - */ -VOID STDCALL -MmUnlockPages(PMDL Mdl) -/* - * FUNCTION: Unlocks the physical pages described by a given MDL - * ARGUMENTS: - * MemoryDescriptorList = MDL describing the buffer to be unlocked - * NOTES: The memory described by the specified MDL must have been locked - * previously by a call to MmProbeAndLockPages. As the pages unlocked, the - * MDL is updated - * - * May be called in any process context. - */ -{ - ULONG i; - PPFN_NUMBER MdlPages; - PFN_NUMBER Page; - - /* - * MmProbeAndLockPages MUST have been called to lock this mdl! - * - * Windows will bugcheck if you pass MmUnlockPages an mdl that hasn't been - * locked with MmLockAndProbePages, but (for now) we'll be more forgiving... - */ - if (!(Mdl->MdlFlags & MDL_PAGES_LOCKED)) - { - DPRINT1("MmUnlockPages called for non-locked mdl!\n"); - return; - } - - /* If mdl buffer is mapped io space -> do nothing */ - if (Mdl->MdlFlags & MDL_IO_SPACE) - { - Mdl->MdlFlags &= ~MDL_PAGES_LOCKED; - return; - } - - /* Automagically undo any calls to MmGetSystemAddressForMdl's for this mdl */ - if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) - { - MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); - } - - /* - * FIXME: I don't know whether this right, but it looks sensible - */ - if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) || - (Mdl->MdlFlags & MDL_IO_PAGE_READ)) - { - return; - } - - - MdlPages = (PPFN_NUMBER)(Mdl + 1); - for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGE_SIZE); i++) - { - Page = MdlPages[i]; - MmUnlockPage(Page); - MmDereferencePage(Page); - } - - Mdl->MdlFlags &= ~MDL_PAGES_LOCKED; -} - - -/* - * @unimplemented - */ -PVOID -STDCALL -MmMapLockedPagesWithReservedMapping ( - IN PVOID MappingAddress, - IN ULONG PoolTag, - IN PMDL MemoryDescriptorList, - IN MEMORY_CACHING_TYPE CacheType - ) -{ - UNIMPLEMENTED; - return 0; -} - - -/* - * @implemented - */ -VOID STDCALL -MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl) -/* - * FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages - * ARGUMENTS: - * BaseAddress = Base virtual address to which the pages were mapped - * MemoryDescriptorList = MDL describing the mapped pages - * - * User space unmappings _must_ be done from the original process context! - */ -{ - KIRQL oldIrql; - ULONG i; - ULONG PageCount; - ULONG Base; - - DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", BaseAddress, Mdl); - - /* - * In this case, the MDL has the same system address as the base address - * so there is no need to free it - */ - if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) && - (BaseAddress >= MmSystemRangeStart)) - { - return; - } - - - /* Calculate the number of pages we mapped. */ - PageCount = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE; - - /* - * Docs says that BaseAddress should be a _base_ address, but every example - * I've seen pass the actual address. -Gunnar - */ - BaseAddress = PAGE_ALIGN(BaseAddress); - - /* Unmap all the pages. */ - for (i = 0; i < PageCount; i++) - { - MmDeleteVirtualMapping(Mdl->Process, - (char*)BaseAddress + (i * PAGE_SIZE), - FALSE, - NULL, - NULL); - } - - if (BaseAddress >= MmSystemRangeStart) - { - ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA); - - KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql); - /* Deallocate all the pages used. */ - Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE; - - RtlClearBits(&MiMdlMappingRegionAllocMap, Base, PageCount); - - MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base); - - KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); - - /* Reset the MDL state. */ - Mdl->MdlFlags &= ~MDL_MAPPED_TO_SYSTEM_VA; - Mdl->MappedSystemVa = NULL; - - } - else - { - MEMORY_AREA *Marea; - - ASSERT(Mdl->Process == PsGetCurrentProcess()); - - Marea = MmLocateMemoryAreaByAddress( (PMADDRESS_SPACE)&(Mdl->Process)->VadRoot, BaseAddress ); - if (Marea == NULL) - { - DPRINT1( "Couldn't open memory area when unmapping user-space pages!\n" ); - KEBUGCHECK(0); - } - - MmFreeMemoryArea( (PMADDRESS_SPACE)&(Mdl->Process)->VadRoot, Marea, NULL, NULL ); - - Mdl->Process = NULL; - } - -} - - -/* - * @unimplemented - */ -VOID -STDCALL -MmUnmapReservedMapping ( - IN PVOID BaseAddress, - IN ULONG PoolTag, - IN PMDL MemoryDescriptorList - ) -{ - UNIMPLEMENTED; -} - - -VOID -NTAPI -MmBuildMdlFromPages(PMDL Mdl, PPFN_TYPE Pages) -{ - memcpy(Mdl + 1, Pages, sizeof(PFN_TYPE) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE)); - - /* FIXME: this flag should be set by the caller perhaps? */ - Mdl->MdlFlags |= MDL_IO_PAGE_READ; -} - - -/* - * @unimplemented - */ -NTSTATUS -STDCALL -MmPrefetchPages ( - IN ULONG NumberOfLists, - IN PREAD_LIST *ReadLists - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - -/* - * @unimplemented - */ -NTSTATUS -STDCALL -MmProtectMdlSystemAddress ( - IN PMDL MemoryDescriptorList, - IN ULONG NewProtect - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - -/* - * @implemented - */ -VOID STDCALL MmProbeAndLockPages (PMDL Mdl, - KPROCESSOR_MODE AccessMode, - LOCK_OPERATION Operation) -/* - * FUNCTION: Probes the specified pages, makes them resident and locks them - * ARGUMENTS: - * Mdl = MDL to probe - * AccessMode = Access at which to probe the buffer - * Operation = Operation to probe for - * - * This function can be seen as a safe version of MmBuildMdlForNonPagedPool - * used in cases where you know that the mdl address is paged memory or - * you don't know where the mdl address comes from. MmProbeAndLockPages will - * work no matter what kind of mdl address you have. - */ -{ - PPFN_TYPE MdlPages; - ULONG i, j; - ULONG NrPages; - NTSTATUS Status; - KPROCESSOR_MODE Mode; - PFN_TYPE Page; - PEPROCESS CurrentProcess = PsGetCurrentProcess(); - PMADDRESS_SPACE AddressSpace; - - DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl); - - ASSERT(!(Mdl->MdlFlags & (MDL_PAGES_LOCKED|MDL_MAPPED_TO_SYSTEM_VA|MDL_PARTIAL| - MDL_IO_SPACE|MDL_SOURCE_IS_NONPAGED_POOL))); - - MdlPages = (PPFN_TYPE)(Mdl + 1); - NrPages = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE; - - /* mdl must have enough page entries */ - ASSERT(NrPages <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE)); - - - if (Mdl->StartVa >= MmSystemRangeStart && - MmGetPfnForProcess(NULL, Mdl->StartVa) >= MmPageArraySize) - { - /* phys addr is not phys memory so this must be io memory */ - - for (i = 0; i < NrPages; i++) - { - MdlPages[i] = MmGetPfnForProcess(NULL, (char*)Mdl->StartVa + (i*PAGE_SIZE)); - } - - Mdl->MdlFlags |= MDL_PAGES_LOCKED|MDL_IO_SPACE; - return; - } - - - if (Mdl->StartVa >= MmSystemRangeStart) - { - /* FIXME: why isn't AccessMode used? */ - Mode = KernelMode; - Mdl->Process = NULL; - AddressSpace = MmGetKernelAddressSpace(); - } - else - { - /* FIXME: why isn't AccessMode used? */ - Mode = UserMode; - Mdl->Process = CurrentProcess; - AddressSpace = (PMADDRESS_SPACE)&(CurrentProcess)->VadRoot; - } - - - /* - * Lock the pages - */ - MmLockAddressSpace(AddressSpace); - - for (i = 0; i < NrPages; i++) - { - PVOID Address; - - Address = (char*)Mdl->StartVa + (i*PAGE_SIZE); - - /* - * FIXME: skip the probing/access stuff if buffer is nonpaged kernel space? - * -Gunnar - */ - - if (!MmIsPagePresent(NULL, Address)) - { - Status = MmAccessFault(FALSE, Address, Mode, NULL); - if (!NT_SUCCESS(Status)) - { - for (j = 0; j < i; j++) - { - Page = MdlPages[j]; - if (Page < MmPageArraySize) - { - MmUnlockPage(Page); - MmDereferencePage(Page); - } - } - MmUnlockAddressSpace(AddressSpace); - ExRaiseStatus(STATUS_ACCESS_VIOLATION); - } - } - else - { - MmLockPage(MmGetPfnForProcess(NULL, Address)); - } - - if ((Operation == IoWriteAccess || Operation == IoModifyAccess) && - (!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE))) - { - Status = MmAccessFault(TRUE, Address, Mode, NULL); - if (!NT_SUCCESS(Status)) - { - for (j = 0; j < i; j++) - { - Page = MdlPages[j]; - if (Page < MmPageArraySize) - { - MmUnlockPage(Page); - MmDereferencePage(Page); - } - } - MmUnlockAddressSpace(AddressSpace); - ExRaiseStatus(STATUS_ACCESS_VIOLATION); - } - } - Page = MmGetPfnForProcess(NULL, Address); - MdlPages[i] = Page; - if (Page >= MmPageArraySize) - Mdl->MdlFlags |= MDL_IO_SPACE; - else - MmReferencePage(Page); - } - - MmUnlockAddressSpace(AddressSpace); - Mdl->MdlFlags |= MDL_PAGES_LOCKED; -} - - -/* - * @unimplemented - */ -VOID -STDCALL -MmProbeAndLockProcessPages ( - IN OUT PMDL MemoryDescriptorList, - IN PEPROCESS Process, - IN KPROCESSOR_MODE AccessMode, - IN LOCK_OPERATION Operation - ) -{ - UNIMPLEMENTED; -} - - -/* - * @unimplemented - */ -VOID -STDCALL -MmProbeAndLockSelectedPages( - IN OUT PMDL MemoryDescriptorList, - IN LARGE_INTEGER PageList[], - IN KPROCESSOR_MODE AccessMode, - IN LOCK_OPERATION Operation - ) -{ - UNIMPLEMENTED; -} - - -/* - * @implemented - */ -ULONG STDCALL MmSizeOfMdl (PVOID Base, - ULONG Length) -/* - * FUNCTION: Returns the number of bytes to allocate for an MDL describing - * the given address range - * ARGUMENTS: - * Base = base virtual address - * Length = number of bytes to map - */ -{ - ULONG len; - - len = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length); - - return(sizeof(MDL)+(len*sizeof(PFN_TYPE))); -} - - -/* - * @implemented - */ -VOID STDCALL -MmBuildMdlForNonPagedPool (PMDL Mdl) -/* - * FUNCTION: Fills in the corresponding physical page array of a given - * MDL for a buffer in nonpaged system space - * ARGUMENTS: - * Mdl = Points to an MDL that supplies a virtual address, - * byte offset and length - * - * This function can be seen as a fast version of MmProbeAndLockPages in case - * you _know_ that the mdl address is within nonpaged kernel space. - */ -{ - ULONG i; - ULONG PageCount; - PPFN_TYPE MdlPages; - - /* - * mdl buffer must (at least) be in kernel space, thou this doesn't - * necesarely mean that the buffer in within _nonpaged_ kernel space... - */ - ASSERT(Mdl->StartVa >= MmSystemRangeStart); - - PageCount = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE; - MdlPages = (PPFN_TYPE)(Mdl + 1); - - /* mdl must have enough page entries */ - ASSERT(PageCount <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE)); - - for (i=0; i < PageCount; i++) - { - *MdlPages++ = MmGetPfnForProcess(NULL, (char*)Mdl->StartVa + (i * PAGE_SIZE)); - } - - Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL; - Mdl->Process = NULL; - Mdl->MappedSystemVa = (char*)Mdl->StartVa + Mdl->ByteOffset; -} - - -/* - * @implemented - */ -PMDL STDCALL -MmCreateMdl (PMDL Mdl, - PVOID Base, - ULONG Length) -/* - * FUNCTION: Allocates and initalizes an MDL - * ARGUMENTS: - * MemoryDescriptorList = Points to MDL to initalize. If this is - * NULL then one is allocated - * Base = Base virtual address of the buffer - * Length = Length in bytes of the buffer - * RETURNS: A pointer to initalized MDL - */ -{ - if (Mdl == NULL) - { - ULONG Size; - - Size = MmSizeOfMdl(Base,Length); - Mdl = - (PMDL)ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL); - if (Mdl == NULL) - { - return(NULL); - } - } - - MmInitializeMdl(Mdl, (char*)Base, Length); - - return(Mdl); -} - - -/* - * @unimplemented - */ -VOID STDCALL -MmMapMemoryDumpMdl (PVOID Unknown0) -/* - * FIXME: Has something to do with crash dumps. Do we want to implement - * this? - */ -{ - UNIMPLEMENTED; -} - - -/* - * @implemented - */ -PMDL STDCALL -MmAllocatePagesForMdl ( IN PHYSICAL_ADDRESS LowAddress, - IN PHYSICAL_ADDRESS HighAddress, - IN PHYSICAL_ADDRESS SkipBytes, - IN SIZE_T Totalbytes ) -{ - /* - MmAllocatePagesForMdl allocates zero-filled, nonpaged, physical memory pages to an MDL - - MmAllocatePagesForMdlSearch the PFN database for free, zeroed or standby - pagesAllocates pages and puts in MDLDoes not map pages (caller responsibility) - Designed to be used by an AGP driver - - LowAddress is the lowest acceptable physical address it wants to allocate - and HighAddress is the highest. SkipBytes are the number of bytes that the - kernel should keep free above LowAddress and below the address at which it - starts to allocate physical memory. TotalBytes are the number of bytes that - the driver wants to allocate. The return value of the function is a MDL - that if non-zero describes the physical memory the kernel has given the - driver. To access portions of the memory the driver must create sub-MDLs - from the returned MDL that describe appropriate portions of the physical - memory. When a driver wants to access physical memory described by a - sub-MDL it must map the sub-MDL using MmGetSystemAddressForMdlSafe. - - Konstantin Gusev - */ - - PMDL Mdl; - PPFN_TYPE Pages; - ULONG NumberOfPagesWanted, NumberOfPagesAllocated; - ULONG Ret; - - DPRINT("MmAllocatePagesForMdl - LowAddress = 0x%I64x, HighAddress = 0x%I64x, " - "SkipBytes = 0x%I64x, Totalbytes = 0x%x\n", - LowAddress.QuadPart, HighAddress.QuadPart, - SkipBytes.QuadPart, Totalbytes); - - /* SkipBytes must be a multiple of the page size */ - if ((SkipBytes.QuadPart % PAGE_SIZE) != 0) - { - DPRINT1("Warning: SkipBytes is not a multiple of PAGE_SIZE\n"); - return NULL; - } - - /* Allocate memory for the MDL */ - Mdl = MmCreateMdl(NULL, 0, Totalbytes); - if (Mdl == NULL) - { - return NULL; - } - - /* Allocate pages into the MDL */ - NumberOfPagesAllocated = 0; - NumberOfPagesWanted = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE; - Pages = (PPFN_TYPE)(Mdl + 1); - while (NumberOfPagesWanted > 0) - { - Ret = MmAllocPagesSpecifyRange( - MC_NPPOOL, - LowAddress, - HighAddress, - NumberOfPagesWanted, - Pages + NumberOfPagesAllocated); - if (Ret == (ULONG)-1) - break; - - NumberOfPagesAllocated += Ret; - NumberOfPagesWanted -= Ret; - - if (SkipBytes.QuadPart == 0) - break; - LowAddress.QuadPart += SkipBytes.QuadPart; - HighAddress.QuadPart += SkipBytes.QuadPart; - } - - if (NumberOfPagesAllocated == 0) - { - ExFreePool(Mdl); - Mdl = NULL; - } - else if (NumberOfPagesWanted > 0) - { - Mdl->ByteCount = (ULONG)(NumberOfPagesAllocated * PAGE_SIZE); - /* FIXME: I don't know if Mdl->Size should also be changed -- blight */ - } - return Mdl; -} - - -/* - * @implemented - */ -VOID STDCALL -MmFreePagesFromMdl ( IN PMDL Mdl ) -{ - /* - Drivers use the MmFreePagesFromMdl, the kernel-mode equivalent of - FreeUserPhysicalPages, to free the physical memory it has allocated with - MmAllocatePagesForMdl. This function is also prototyped in ntddk.h: - - Note that a driver is responsible for deallocating the MDL returned by - MmAllocatePagesForMdl with a call to ExFreePool, since MmFreePagesFromMdl - does not free the MDL. - - Konstantin Gusev - - */ - PPFN_TYPE Pages; - LONG NumberOfPages; - - NumberOfPages = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE; - Pages = (PPFN_TYPE)(Mdl + 1); - - while (--NumberOfPages >= 0) - { - MmDereferencePage(Pages[NumberOfPages]); - } -} - - -/* - * @implemented - */ -PVOID STDCALL -MmMapLockedPagesSpecifyCache ( IN PMDL Mdl, - IN KPROCESSOR_MODE AccessMode, - IN MEMORY_CACHING_TYPE CacheType, - IN PVOID BaseAddress, - IN ULONG BugCheckOnFailure, - IN MM_PAGE_PRIORITY Priority) -{ - PVOID Base; - PULONG MdlPages; - KIRQL oldIrql; - ULONG PageCount; - ULONG StartingOffset; - PEPROCESS CurrentProcess; - NTSTATUS Status; - ULONG Protect; - - DPRINT("MmMapLockedPagesSpecifyCache(Mdl 0x%x, AccessMode 0x%x, CacheType 0x%x, " - "BaseAddress 0x%x, BugCheckOnFailure 0x%x, Priority 0x%x)\n", - Mdl, AccessMode, CacheType, BaseAddress, BugCheckOnFailure, Priority); - - /* FIXME: Implement Priority */ - (void) Priority; - - Protect = PAGE_READWRITE; - if (CacheType == MmNonCached) - Protect |= PAGE_NOCACHE; - else if (CacheType == MmWriteCombined) - DPRINT("CacheType MmWriteCombined not supported!\n"); - - /* Calculate the number of pages required. */ - PageCount = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE; - - if (AccessMode != KernelMode) - { - MEMORY_AREA *Result; - LARGE_INTEGER BoundaryAddressMultiple; - NTSTATUS Status; - - /* pretty sure you can't map partial mdl's to user space */ - ASSERT(!(Mdl->MdlFlags & MDL_PARTIAL)); - - BoundaryAddressMultiple.QuadPart = 0; - Base = BaseAddress; - - CurrentProcess = PsGetCurrentProcess(); - - MmLockAddressSpace((PMADDRESS_SPACE)&CurrentProcess->VadRoot); - Status = MmCreateMemoryArea((PMADDRESS_SPACE)&CurrentProcess->VadRoot, - MEMORY_AREA_MDL_MAPPING, - &Base, - PageCount * PAGE_SIZE, - Protect, - &Result, - (Base != NULL), - 0, - BoundaryAddressMultiple); - MmUnlockAddressSpace((PMADDRESS_SPACE)&CurrentProcess->VadRoot); - if (!NT_SUCCESS(Status)) - { - if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) - { - return NULL; - } - - /* Throw exception */ - ExRaiseStatus(STATUS_ACCESS_VIOLATION); - ASSERT(0); - } - - Mdl->Process = (PEPROCESS)CurrentProcess; - } - else /* if (AccessMode == KernelMode) */ - { - /* can't map mdl twice */ - ASSERT(!(Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA|MDL_PARTIAL_HAS_BEEN_MAPPED))); - /* can't map mdl buildt from non paged pool into kernel space */ - ASSERT(!(Mdl->MdlFlags & (MDL_SOURCE_IS_NONPAGED_POOL))); - - CurrentProcess = NULL; - - /* Allocate that number of pages from the mdl mapping region. */ - KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql); - - StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, PageCount, MiMdlMappingRegionHint); - - if (StartingOffset == 0xffffffff) - { - KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); - - DPRINT1("Out of MDL mapping space\n"); - - if ((Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) || !BugCheckOnFailure) - { - return NULL; - } - - KEBUGCHECK(0); - } - - Base = (PVOID)((ULONG_PTR)MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE); - - if (MiMdlMappingRegionHint == StartingOffset) - { - MiMdlMappingRegionHint += PageCount; - } - - KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); - - Mdl->Process = NULL; - } - - /* Set the virtual mappings for the MDL pages. */ - MdlPages = (PULONG)(Mdl + 1); - - if (Mdl->MdlFlags & MDL_IO_SPACE) - Status = MmCreateVirtualMappingUnsafe(CurrentProcess, - Base, - Protect, - MdlPages, - PageCount); - else - Status = MmCreateVirtualMapping(CurrentProcess, - Base, - Protect, - MdlPages, - PageCount); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) - { - return NULL; - } - if (AccessMode != KernelMode) - { - /* Throw exception */ - ExRaiseStatus(STATUS_ACCESS_VIOLATION); - ASSERT(0); - } - else /* AccessMode == KernelMode */ - { - if (!BugCheckOnFailure) - return NULL; - - /* FIXME: Use some bugcheck code instead of 0 */ - KEBUGCHECK(0); - } - } - - /* Mark the MDL has having being mapped. */ - if (AccessMode == KernelMode) - { - if (Mdl->MdlFlags & MDL_PARTIAL) - { - Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED; - } - else - { - Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA; - } - Mdl->MappedSystemVa = (char*)Base + Mdl->ByteOffset; - } - else - DPRINT1("UserMode mapping - returning 0x%x\n", (ULONG)Base + Mdl->ByteOffset); - - return((char*)Base + Mdl->ByteOffset); -} - - -/* - * @implemented - */ -PVOID STDCALL -MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode) -/* - * FUNCTION: Maps the physical pages described by a given MDL - * ARGUMENTS: - * Mdl = Points to an MDL updated by MmProbeAndLockPages, MmBuildMdlForNonPagedPool, - * MmAllocatePagesForMdl or IoBuildPartialMdl. - * AccessMode = Specifies the portion of the address space to map the - * pages. - * RETURNS: The base virtual address that maps the locked pages for the - * range described by the MDL - * - * If mapping into user space, pages are mapped into current address space. - */ -{ - return MmMapLockedPagesSpecifyCache(Mdl, - AccessMode, - MmCached, - NULL, - TRUE, - NormalPagePriority); -} - - -/* EOF */ - - - - - - - - -
Removed: branches/cache_manager_rewrite/mm/process.c URL: http://svn.reactos.org/svn/reactos/branches/cache_manager_rewrite/mm/process... ============================================================================== --- branches/cache_manager_rewrite/mm/process.c (original) +++ branches/cache_manager_rewrite/mm/process.c (removed) @@ -1,687 +1,0 @@ -/* - * 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; -extern ULONG NtGlobalFlag; -extern MM_SYSTEMSIZE MmSystemSize; - -#define MM_HIGHEST_VAD_ADDRESS \ - (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -NTAPI -MmSetMemoryPriorityProcess(IN PEPROCESS Process, - IN UCHAR MemoryPriority) -{ - UCHAR OldPriority; - - /* Check if we have less then 16MB of Physical Memory */ - if ((MmSystemSize == MmSmallSystem) && - (MmStats.NrTotalPages < ((15 * 1024 * 1024) / PAGE_SIZE))) - { - /* Always use background priority */ - MemoryPriority = 0; - } - - /* Save the old priority and update it */ - OldPriority = Process->Vm.Flags.MemoryPriority; - Process->Vm.Flags.MemoryPriority = MemoryPriority; - - /* Return the old priority */ - return OldPriority; -} - -LCID -NTAPI -MmGetSessionLocaleId(VOID) -{ - PEPROCESS Process; - PAGED_CODE(); - - /* Get the current process */ - Process = PsGetCurrentProcess(); - - /* Check if it's the Session Leader */ - if (Process->Vm.Flags.SessionLeader) - { - /* Make sure it has a valid Session */ - if (Process->Session) - { - /* Get the Locale ID */ -#if ROS_HAS_SESSIONS - return ((PMM_SESSION_SPACE)Process->Session)->LocaleId; -#endif - } - } - - /* Not a session leader, return the default */ - return PsDefaultThreadLocaleId; -} - -PVOID -STDCALL -MiCreatePebOrTeb(PEPROCESS Process, - PVOID BaseAddress) -{ - NTSTATUS Status; - PMADDRESS_SPACE ProcessAddressSpace = (PMADDRESS_SPACE)&Process->VadRoot; - PMEMORY_AREA MemoryArea; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - PVOID AllocatedBase = BaseAddress; - BoundaryAddressMultiple.QuadPart = 0; - - /* Acquire the Lock */ - MmLockAddressSpace(ProcessAddressSpace); - - /* - * Create a Peb or Teb. - * Loop until it works, decreasing by PAGE_SIZE each time. The logic here - * is that a PEB allocation should never fail since the address is free, - * while TEB allocation can fail, and we should simply try the address - * below. Is there a nicer way of doing this automagically? (ie: findning) - * a gap region? -- Alex - */ - do { - DPRINT("Trying to allocate: %x\n", AllocatedBase); - Status = MmCreateMemoryArea(ProcessAddressSpace, - MEMORY_AREA_PEB_OR_TEB, - &AllocatedBase, - PAGE_SIZE, - PAGE_READWRITE, - &MemoryArea, - TRUE, - 0, - BoundaryAddressMultiple); - AllocatedBase = RVA(AllocatedBase, -PAGE_SIZE); - } while (Status != STATUS_SUCCESS); - - /* Initialize the Region */ - MmInitializeRegion(&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 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 -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()); -} - -VOID -STDCALL -MmDeleteTeb(PEPROCESS Process, - PTEB Teb) -{ - PMADDRESS_SPACE ProcessAddressSpace = (PMADDRESS_SPACE)&Process->VadRoot; - PMEMORY_AREA MemoryArea; - - /* Lock the Address Space */ - MmLockAddressSpace(ProcessAddressSpace); - - MemoryArea = MmLocateMemoryAreaByAddress(ProcessAddressSpace, (PVOID)Teb); - if (MemoryArea) - { - /* Delete the Teb */ - MmFreeVirtualMemory(Process, MemoryArea); - } - - /* Unlock the Address Space */ - MmUnlockAddressSpace(ProcessAddressSpace); -} - -PVOID -STDCALL -MmCreateKernelStack(BOOLEAN GuiStack) -{ - 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(0); - } - - /* - * 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(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 */ - return STATUS_SUCCESS; -} - -NTSTATUS -STDCALL -MmCreatePeb(PEPROCESS Process) -{ - PPEB Peb = NULL; - LARGE_INTEGER SectionOffset; - 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(ExpNlsSectionPointer, - (PEPROCESS)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); - - /* 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->InheritedAddressSpace = 0; - Peb->Mutant = NULL; - - /* NLS */ - Peb->AnsiCodePageData = (PCHAR)TableBase + ExpAnsiCodePageDataOffset; - Peb->OemCodePageData = (PCHAR)TableBase + ExpOemCodePageDataOffset; - Peb->UnicodeCaseTableData = (PCHAR)TableBase + ExpUnicodeCaseTableDataOffset; - - /* Default Version Data (could get changed below) */ - Peb->OSMajorVersion = NtMajorVersion; - Peb->OSMinorVersion = NtMinorVersion; - Peb->OSBuildNumber = 2195; - Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */ - Peb->OSCSDVersion = NtOSCSDVersion; - - /* Heap and Debug Data */ - Peb->NumberOfProcessors = KeNumberProcessors; - Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE); - Peb->NtGlobalFlag = NtGlobalFlag; - /*Peb->HeapSegmentReserve = MmHeapSegmentReserve; - Peb->HeapSegmentCommit = MmHeapSegmentCommit; - Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold; - Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;*/ - Peb->NumberOfHeaps = 0; - Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID); - Peb->ProcessHeaps = (PVOID*)Peb + 1; - - /* Image Data */ - if ((NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress))) - { - /* Write subsystem data */ - Peb->ImageSubSystem = NtHeaders->OptionalHeader.Subsystem; - Peb->ImageSubSystemMajorVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion; - Peb->ImageSubSystemMinorVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion; - - /* Write Version Data */ - if (NtHeaders->OptionalHeader.Win32VersionValue) - { - Peb->OSMajorVersion = NtHeaders->OptionalHeader.Win32VersionValue & 0xFF; - Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF; - Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF; - - /* Set the Platform ID */ - Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2; - } - - /* Check if the image is not safe for SMP */ - if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) - { - /* FIXME: Choose one randomly */ - Peb->ImageProcessAffinityMask = 1; - } - else - { - /* Use affinity from Image Header */ - Peb->ImageProcessAffinityMask = ProcessAffinityMask; - } - - _SEH_TRY - { - /* Get the Image Config Data too */ - ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, - &ViewSize); - - ProbeForRead(ImageConfigData, - sizeof(IMAGE_LOAD_CONFIG_DIRECTORY), - sizeof(ULONG)); - - /* Process the image config data overrides if specfied. */ - if (ImageConfigData != NULL) - { - if (ImageConfigData->CSDVersion) - { - Peb->OSCSDVersion = ImageConfigData->CSDVersion; - } - if (ImageConfigData->ProcessAffinityMask) - { - ProcessAffinityMask = ImageConfigData->ProcessAffinityMask; - } - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - - /* Misc data */ - Peb->SessionId = Process->Session; - Process->Peb = Peb; - - /* Detach from the Process */ - KeDetachProcess(); - - DPRINT("MmCreatePeb: Peb created at %p\n", Peb); - return Status; -} - -PTEB -STDCALL -MmCreateTeb(PEPROCESS Process, - PCLIENT_ID ClientId, - PINITIAL_TEB InitialTeb) -{ - PTEB Teb; - BOOLEAN Attached = FALSE; - - /* Attach to the process */ - DPRINT("MmCreateTeb\n"); - if (Process != PsGetCurrentProcess()) - { - /* Attach to Target */ - KeAttachProcess(&Process->Pcb); - Attached = TRUE; - } - - /* Allocate the TEB */ - Teb = MiCreatePebOrTeb(Process, - (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); - - /* Initialize the PEB */ - RtlZeroMemory(Teb, sizeof(TEB)); - - /* Set TIB Data */ - Teb->Tib.ExceptionList = (PVOID)0xFFFFFFFF; - Teb->Tib.Version = 1; - Teb->Tib.Self = (PNT_TIB)Teb; - - /* Set TEB Data */ - Teb->Cid = *ClientId; - Teb->RealClientId = *ClientId; - Teb->ProcessEnvironmentBlock = Process->Peb; - Teb->CurrentLocale = PsDefaultThreadLocaleId; - - /* Store stack information from InitialTeb */ - if(InitialTeb != NULL) - { - Teb->Tib.StackBase = InitialTeb->StackBase; - Teb->Tib.StackLimit = InitialTeb->StackLimit; - Teb->DeallocationStack = InitialTeb->AllocatedStackBase; - } - - /* Return TEB Address */ - DPRINT("Allocated: %x\n", Teb); - if (Attached) KeDetachProcess(); - return Teb; -} - -NTSTATUS -STDCALL -MmCreateProcessAddressSpace(IN PEPROCESS Process, - IN PROS_SECTION_OBJECT Section OPTIONAL, - IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL) -{ - NTSTATUS Status; - PMADDRESS_SPACE ProcessAddressSpace = (PMADDRESS_SPACE)&Process->VadRoot; - PVOID BaseAddress; - PMEMORY_AREA MemoryArea; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - SIZE_T ViewSize = 0; - PVOID ImageBase = 0; - BoundaryAddressMultiple.QuadPart = 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(ProcessAddressSpace, - MEMORY_AREA_NO_ACCESS, - &BaseAddress, - 0x10000, - PAGE_NOACCESS, - &MemoryArea, - FALSE, - 0, - 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(ProcessAddressSpace, - MEMORY_AREA_NO_ACCESS, - &BaseAddress, - 0x10000 - PAGE_SIZE, - PAGE_NOACCESS, - &MemoryArea, - FALSE, - 0, - 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(ProcessAddressSpace, - MEMORY_AREA_SHARED_DATA, - &BaseAddress, - PAGE_SIZE, - PAGE_EXECUTE_READ, - &MemoryArea, - FALSE, - 0, - BoundaryAddressMultiple); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create Shared User Data\n"); - goto exit; - } - - /* The process now has an address space */ - Process->HasAddressSpace = TRUE; - - /* 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, - (PEPROCESS)Process, - (PVOID*)&ImageBase, - 0, - 0, - NULL, - &ViewSize, - 0, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to map process Image\n"); - return Status; - } - - /* 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); - while (szSrc >= FileName.Buffer) - { - /* Make sure this isn't a backslash */ - if (*--szSrc == OBJ_NAME_PATH_SEPARATOR) - { - /* If so, stop it here */ - szSrc++; - break; - } - else - { - /* Otherwise, keep going */ - lnFName++; - } - } - - /* Copy the to the process and truncate it to 15 characters if necessary */ - szDest = Process->ImageFileName; - lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1); - while (lnFName--) *szDest++ = (UCHAR)*szSrc++; - *szDest = UNICODE_NULL; - - /* Check if caller wants an audit name */ - if (AuditName) - { - /* Setup the audit name */ - SeInitializeProcessAuditName(Section->FileObject, - FALSE, - AuditName); - } - - /* Return status to caller */ - return Status; - } - -exit: - /* Unlock the Address Space */ - DPRINT("Unlocking\n"); - MmUnlockAddressSpace(ProcessAddressSpace); - - /* Return status to caller */ - return Status; -} - -VOID -NTAPI -MmCleanProcessAddressSpace(IN PEPROCESS Process) -{ - /* FIXME: Add part of MmDeleteProcessAddressSpace here */ -} - -NTSTATUS -NTAPI -MmDeleteProcessAddressSpace(PEPROCESS Process) -{ - PVOID Address; - PMEMORY_AREA MemoryArea; - - DPRINT("MmDeleteProcessAddressSpace(Process %x (%s))\n", Process, - Process->ImageFileName); - - MmLockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot); - - while ((MemoryArea = ((PMADDRESS_SPACE)&Process->VadRoot)->MemoryAreaRoot) != NULL) - { - switch (MemoryArea->Type) - { - case MEMORY_AREA_SECTION_VIEW: - Address = (PVOID)MemoryArea->StartingAddress; - MmUnlockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot); - MmUnmapViewOfSection(Process, Address); - MmLockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot); - break; - - case MEMORY_AREA_VIRTUAL_MEMORY: - case MEMORY_AREA_PEB_OR_TEB: - MmFreeVirtualMemory(Process, MemoryArea); - break; - - case MEMORY_AREA_SHARED_DATA: - case MEMORY_AREA_NO_ACCESS: - MmFreeMemoryArea((PMADDRESS_SPACE)&Process->VadRoot, - MemoryArea, - NULL, - NULL); - break; - - case MEMORY_AREA_MDL_MAPPING: - KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES); - break; - - default: - KEBUGCHECK(0); - } - } - - Mmi386ReleaseMmInfo(Process); - - MmUnlockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot); - MmDestroyAddressSpace((PMADDRESS_SPACE)&Process->VadRoot); - - DPRINT("Finished MmReleaseMmInfo()\n"); - return(STATUS_SUCCESS); -}