Author: sir_richard
Date: Wed Oct 6 04:34:36 2010
New Revision: 49008
URL: http://svn.reactos.org/svn/reactos?rev=49008&view=rev
Log:
Lame... build fix.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed Oct 6 04:34:36 2010
@@ -1194,6 +1194,12 @@
IN PVOID InputSession OPTIONAL
);
+ULONG
+NTAPI
+MiMakeProtectionMask(
+ IN ULONG Protect
+);
+
//
// MiRemoveZeroPage will use inline code to zero out the page manually if only
// free pages are available. In some scenarios, we don't/can't run that piece of
Author: fireball
Date: Tue Oct 5 21:43:48 2010
New Revision: 49007
URL: http://svn.reactos.org/svn/reactos?rev=49007&view=rev
Log:
[RTL/HEAP]
- First commit of a heap manager rewrite. It introduces a totally new heap manager, with the following features:
* Actually resembles real NT's heap manager;
* Based on data structures similar to Windows 2003 and Vista+'s heap structures;
* Supporting advanced heap flags (e.g. useful for debugging);
* Substantially lower fragmentation rates (and thus speed and reliability) than the existing Wine's implementation. It's going to be further enhanced by adding a frontend allocator (for example, as lookaside lists, or as a Low Fragmentation Heap alike frontend in Vista+ systems);
* Real support for user-defined flags and native support for user-defined values;
* Native support for a custom commit routine, which is very important for trunk's win32 subsystem;
* Reserving, committing, decommitting and freeing on the fly, unlike existing heap manager which prefers to reserve and commit as much as possible, and doesn't decommit when it's no longer necessary;
* Support for per process heaps, with a proper lock;
* Reserved support for a special so-called debug heap allocator (to be implemented in heapdbg.c) which will be useful for finding heap corruptions.
The committed code is a result of a month of work, and is a heavy work-in-progress one. It already implements the bare minimum required to boot to 3rd stage and run FireFox 3, however many rare codepaths are not implemented yet and there is some maintenance work to do (e.g. move structures and defines to a standalone header file). A list of used references is stated in the header of a source file for now.
Added:
trunk/reactos/lib/rtl/heap_rewrite.c (with props)
trunk/reactos/lib/rtl/heapdbg.c (with props)
Modified:
trunk/reactos/lib/rtl/rtl.rbuild
[This mail would be too long, it was shortened to contain the URLs only.]
Added: trunk/reactos/lib/rtl/heap_rewrite.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap_rewrite.c?rev…
Added: trunk/reactos/lib/rtl/heapdbg.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heapdbg.c?rev=4900…
Modified: trunk/reactos/lib/rtl/rtl.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtl.rbuild?rev=490…
Author: sir_richard
Date: Tue Oct 5 20:00:32 2010
New Revision: 49004
URL: http://svn.reactos.org/svn/reactos?rev=49004&view=rev
Log:
[NTOS]: High-level interface fixes to NtAllocateVirtualMemory/NtFreeVirtualMemory:
- Validate MEM_LARGE_PAGES, MEM_PHYSICAL flags. Check for permission to use MEM_LARGE_PAGES.
- Validate protection mask.
- Validate MEM_RELEASE and MEM_DECOMMIT.
- Perform correct SEH in NtFreeVirtualMemory.
- Protect against overflows past VAD/User address ranegs.
- Only reference the process by handle if this isn't already the current process.
- If this isn't the current process, attach to it during the duration of the VM operation.
Modified:
trunk/reactos/ntoskrnl/mm/anonmem.c
Modified: trunk/reactos/ntoskrnl/mm/anonmem.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/anonmem.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/anonmem.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/anonmem.c [iso-8859-1] Tue Oct 5 20:00:32 2010
@@ -42,6 +42,9 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
+
+#define MODULE_INVOLVED_IN_ARM3
+#include "ARM3/miarm.h"
/* FUNCTIONS *****************************************************************/
@@ -663,31 +666,14 @@
/*
* @implemented
*/
-NTSTATUS NTAPI
-NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
+NTSTATUS
+NTAPI
+NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
IN OUT PVOID* UBaseAddress,
- IN ULONG_PTR ZeroBits,
+ IN ULONG_PTR ZeroBits,
IN OUT PSIZE_T URegionSize,
- IN ULONG AllocationType,
- IN ULONG Protect)
-/*
- * FUNCTION: Allocates a block of virtual memory in the process address space
- * ARGUMENTS:
- * ProcessHandle = The handle of the process which owns the virtual memory
- * BaseAddress = A pointer to the virtual memory allocated. If you
- * supply a non zero value the system will try to
- * allocate the memory at the address supplied. It round
- * it down to a multiple of the page size.
- * ZeroBits = (OPTIONAL) You can specify the number of high order bits
- * that must be zero, ensuring that the memory will be
- * allocated at a address below a certain value.
- * RegionSize = The number of bytes to allocate
- * AllocationType = Indicates the type of virtual memory you like to
- * allocated, can be a combination of MEM_COMMIT,
- * MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN.
- * Protect = Indicates the protection type of the pages allocated.
- * RETURNS: Status
- */
+ IN ULONG AllocationType,
+ IN ULONG Protect)
{
PEPROCESS Process;
MEMORY_AREA* MemoryArea;
@@ -699,132 +685,188 @@
ULONG RegionSize;
PVOID PBaseAddress;
ULONG PRegionSize;
- ULONG MemProtection;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
- KPROCESSOR_MODE PreviousMode;
-
- PAGED_CODE();
-
- DPRINT("NtAllocateVirtualMemory(*UBaseAddress %x, "
- "ZeroBits %d, *URegionSize %x, AllocationType %x, Protect %x)\n",
- *UBaseAddress,ZeroBits,*URegionSize,AllocationType,
- Protect);
-
- /* Check for valid protection flags */
- MemProtection = Protect & ~(PAGE_GUARD|PAGE_NOCACHE);
- if (MemProtection != PAGE_NOACCESS &&
- MemProtection != PAGE_READONLY &&
- MemProtection != PAGE_READWRITE &&
- MemProtection != PAGE_WRITECOPY &&
- MemProtection != PAGE_EXECUTE &&
- MemProtection != PAGE_EXECUTE_READ &&
- MemProtection != PAGE_EXECUTE_READWRITE &&
- MemProtection != PAGE_EXECUTE_WRITECOPY)
- {
- DPRINT1("Invalid page protection\n");
- return STATUS_INVALID_PAGE_PROTECTION;
- }
-
- /* Check for valid Zero bits */
- if (ZeroBits > 21)
- {
- DPRINT1("Too many zero bits\n");
- return STATUS_INVALID_PARAMETER_3;
- }
-
- /* Check for valid Allocation Types */
- if ((AllocationType & ~(MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_PHYSICAL |
- MEM_TOP_DOWN | MEM_WRITE_WATCH)))
- {
- DPRINT1("Invalid Allocation Type\n");
- return STATUS_INVALID_PARAMETER_5;
- }
-
- /* Check for at least one of these Allocation Types to be set */
- if (!(AllocationType & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)))
- {
- DPRINT1("No memory allocation base type\n");
- return STATUS_INVALID_PARAMETER_5;
- }
-
- /* MEM_RESET is an exclusive flag, make sure that is valid too */
- if ((AllocationType & MEM_RESET) && (AllocationType != MEM_RESET))
- {
- DPRINT1("Invalid use of MEM_RESET\n");
- return STATUS_INVALID_PARAMETER_5;
- }
-
- /* MEM_WRITE_WATCH can only be used if MEM_RESERVE is also used */
- if ((AllocationType & MEM_WRITE_WATCH) && !(AllocationType & MEM_RESERVE))
- {
- DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n");
- return STATUS_INVALID_PARAMETER_5;
- }
-
- /* MEM_PHYSICAL can only be used with MEM_RESERVE, and can only be R/W */
- if (AllocationType & MEM_PHYSICAL)
- {
- /* First check for MEM_RESERVE exclusivity */
- if (AllocationType != (MEM_RESERVE | MEM_PHYSICAL))
- {
- DPRINT1("MEM_PHYSICAL used with other flags then MEM_RESERVE or"
- "MEM_RESERVE was not present at all\n");
- return STATUS_INVALID_PARAMETER_5;
- }
-
- /* Then make sure PAGE_READWRITE is used */
- if (Protect != PAGE_READWRITE)
- {
- DPRINT1("MEM_PHYSICAL used without PAGE_READWRITE\n");
- return STATUS_INVALID_PAGE_PROTECTION;
- }
- }
-
- PreviousMode = KeGetPreviousMode();
-
- _SEH2_TRY
- {
- if (PreviousMode != KernelMode)
- {
- ProbeForWritePointer(UBaseAddress);
- ProbeForWriteUlong(URegionSize);
- }
- PBaseAddress = *UBaseAddress;
- PRegionSize = *URegionSize;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Return the exception code */
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
- }
- _SEH2_END;
-
- BoundaryAddressMultiple.QuadPart = 0;
+ PEPROCESS CurrentProcess = PsGetCurrentProcess();
+ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
+ KAPC_STATE ApcState;
+ ULONG ProtectionMask;
+ BOOLEAN Attached = FALSE;
+ BoundaryAddressMultiple.QuadPart = 0;
+ PAGED_CODE();
+
+ /* Check for valid Zero bits */
+ if (ZeroBits > 21)
+ {
+ DPRINT1("Too many zero bits\n");
+ return STATUS_INVALID_PARAMETER_3;
+ }
+
+ /* Check for valid Allocation Types */
+ if ((AllocationType & ~(MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_PHYSICAL |
+ MEM_TOP_DOWN | MEM_WRITE_WATCH)))
+ {
+ DPRINT1("Invalid Allocation Type\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Check for at least one of these Allocation Types to be set */
+ if (!(AllocationType & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)))
+ {
+ DPRINT1("No memory allocation base type\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* MEM_RESET is an exclusive flag, make sure that is valid too */
+ if ((AllocationType & MEM_RESET) && (AllocationType != MEM_RESET))
+ {
+ DPRINT1("Invalid use of MEM_RESET\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Check if large pages are being used */
+ if (AllocationType & MEM_LARGE_PAGES)
+ {
+ /* Large page allocations MUST be committed */
+ if (!(AllocationType & MEM_COMMIT))
+ {
+ DPRINT1("Must supply MEM_COMMIT with MEM_LARGE_PAGES\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* These flags are not allowed with large page allocations */
+ if (AllocationType & (MEM_PHYSICAL | MEM_RESET | MEM_WRITE_WATCH))
+ {
+ DPRINT1("Using illegal flags with MEM_LARGE_PAGES\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+ }
+
+ /* MEM_WRITE_WATCH can only be used if MEM_RESERVE is also used */
+ if ((AllocationType & MEM_WRITE_WATCH) && !(AllocationType & MEM_RESERVE))
+ {
+ DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* MEM_PHYSICAL can only be used if MEM_RESERVE is also used */
+ if ((AllocationType & MEM_PHYSICAL) && !(AllocationType & MEM_RESERVE))
+ {
+ DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Check for valid MEM_PHYSICAL usage */
+ if (AllocationType & MEM_PHYSICAL)
+ {
+ /* Only these flags are allowed with MEM_PHYSIAL */
+ if (AllocationType & ~(MEM_RESERVE | MEM_TOP_DOWN | MEM_PHYSICAL))
+ {
+ DPRINT1("Using illegal flags with MEM_PHYSICAL\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Then make sure PAGE_READWRITE is used */
+ if (Protect != PAGE_READWRITE)
+ {
+ DPRINT1("MEM_PHYSICAL used without PAGE_READWRITE\n");
+ return STATUS_INVALID_PARAMETER_6;
+ }
+ }
+
+ /* Calculate the protection mask and make sure it's valid */
+ ProtectionMask = MiMakeProtectionMask(Protect);
+ if (ProtectionMask == MM_INVALID_PROTECTION)
+ {
+ DPRINT1("Invalid protection mask\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
+
+ /* Enter SEH */
+ _SEH2_TRY
+ {
+ /* Check for user-mode parameters */
+ if (PreviousMode != KernelMode)
+ {
+ /* Make sure they are writable */
+ ProbeForWritePointer(UBaseAddress);
+ ProbeForWriteUlong(URegionSize);
+ }
+
+ /* Capture their values */
+ PBaseAddress = *UBaseAddress;
+ PRegionSize = *URegionSize;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ /* Make sure the allocation isn't past the VAD area */
+ if (PBaseAddress >= MM_HIGHEST_VAD_ADDRESS)
+ {
+ DPRINT1("Virtual allocation base above User Space\n");
+ return STATUS_INVALID_PARAMETER_2;
+ }
+
+ /* Make sure the allocation wouldn't overflow past the VAD area */
+ if ((((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) - (ULONG_PTR)PBaseAddress) < PRegionSize)
+ {
+ DPRINT1("Region size would overflow into kernel-memory\n");
+ return STATUS_INVALID_PARAMETER_4;
+ }
+
+ /* Make sure there's a size specified */
+ if (!PRegionSize)
+ {
+ DPRINT1("Region size is invalid (zero)\n");
+ return STATUS_INVALID_PARAMETER_4;
+ }
+
+ /* Check if this is for the current process */
+ if (ProcessHandle == NtCurrentProcess())
+ {
+ /* We already have the current process, no need to go through Ob */
+ Process = CurrentProcess;
+ }
+ else
+ {
+ /* Reference the handle for correct permissions */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_OPERATION,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&Process,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check if not running in the current process */
+ if (CurrentProcess != Process)
+ {
+ /* Attach to it */
+ KeStackAttachProcess(&Process->Pcb, &ApcState);
+ Attached = TRUE;
+ }
+ }
+
+ /* Check for large page allocations */
+ if (AllocationType & MEM_LARGE_PAGES)
+ {
+ /* The lock memory privilege is required */
+ if (!SeSinglePrivilegeCheck(SeLockMemoryPrivilege, PreviousMode))
+ {
+ /* Fail without it */
+ DPRINT1("Privilege not held for MEM_LARGE_PAGES\n");
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+ return STATUS_PRIVILEGE_NOT_HELD;
+ }
+ }
BaseAddress = (PVOID)PAGE_ROUND_DOWN(PBaseAddress);
RegionSize = PAGE_ROUND_UP((ULONG_PTR)PBaseAddress + PRegionSize) -
PAGE_ROUND_DOWN(PBaseAddress);
- /*
- * We've captured and calculated the data, now do more checks
- * Yes, MmCreateMemoryArea does similar checks, but they don't return
- * the right status codes that a caller of this routine would expect.
- */
- if ((ULONG_PTR)BaseAddress >= USER_SHARED_DATA)
- {
- DPRINT1("Virtual allocation base above User Space\n");
- return STATUS_INVALID_PARAMETER_2;
- }
- if (!RegionSize)
- {
- DPRINT1("Region size is invalid (zero)\n");
- return STATUS_INVALID_PARAMETER_4;
- }
- if ((USER_SHARED_DATA - (ULONG_PTR)BaseAddress) < RegionSize)
- {
- DPRINT1("Region size would overflow into kernel-memory\n");
- return STATUS_INVALID_PARAMETER_4;
- }
/*
* Copy on Write is reserved for system use. This case is a certain failure
@@ -835,19 +877,6 @@
{
DPRINT1("Copy on write is not supported by VirtualAlloc\n");
return STATUS_INVALID_PAGE_PROTECTION;
- }
-
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_OPERATION,
- PsProcessType,
- PreviousMode,
- (PVOID*)(&Process),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
- return(Status);
}
Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE;
@@ -871,8 +900,8 @@
(ULONG_PTR)BaseAddress + RegionSize, MemoryArea->EndingAddress);
MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
-
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
return STATUS_MEMORY_NOT_ALLOCATED;
}
@@ -888,7 +917,8 @@
}
MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
/* MEM_RESET does not modify any attributes of region */
return STATUS_SUCCESS;
@@ -904,7 +934,8 @@
BaseAddress, RegionSize,
Type, Protect, MmModifyAttributes);
MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
/* Give the caller rounded BaseAddress and area length */
@@ -935,7 +966,8 @@
}
MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
/* Give the caller rounded BaseAddress and area length */
@@ -951,7 +983,8 @@
else
{
MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
return(STATUS_UNSUCCESSFUL);
}
}
@@ -969,7 +1002,8 @@
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
return(Status);
}
@@ -986,13 +1020,15 @@
const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
MmReserveSwapPages(nPages);
}
+
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
*UBaseAddress = BaseAddress;
*URegionSize = MemoryAreaLength;
DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize);
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
@@ -1261,8 +1297,8 @@
*/
NTSTATUS NTAPI
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID* PBaseAddress,
- IN PSIZE_T PRegionSize,
+ IN PVOID* UBaseAddress,
+ IN PSIZE_T URegionSize,
IN ULONG FreeType)
/*
* FUNCTION: Frees a range of virtual memory
@@ -1281,51 +1317,94 @@
NTSTATUS Status;
PEPROCESS Process;
PMMSUPPORT AddressSpace;
- PVOID BaseAddress;
- ULONG RegionSize;
-
- PAGED_CODE();
-
- DPRINT("NtFreeVirtualMemory(ProcessHandle %x, *PBaseAddress %x, "
- "*PRegionSize %x, FreeType %x)\n",ProcessHandle,*PBaseAddress,
- *PRegionSize,FreeType);
-
+ PVOID BaseAddress, PBaseAddress;
+ ULONG RegionSize, PRegionSize;
+ PEPROCESS CurrentProcess = PsGetCurrentProcess();
+ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
+ KAPC_STATE ApcState;
+ BOOLEAN Attached = FALSE;
+ PAGED_CODE();
+
+ /* Only two flags are supported */
if (!(FreeType & (MEM_RELEASE | MEM_DECOMMIT)))
{
DPRINT1("Invalid FreeType\n");
return STATUS_INVALID_PARAMETER_4;
}
-
- if (ExGetPreviousMode() != KernelMode)
- {
- _SEH2_TRY
+
+ /* Check if no flag was used, or if both flags were used */
+ if (!((FreeType & (MEM_DECOMMIT | MEM_RELEASE))) ||
+ ((FreeType & (MEM_DECOMMIT | MEM_RELEASE)) == (MEM_DECOMMIT | MEM_RELEASE)))
+ {
+ DPRINT1("Invalid FreeType combination\n");
+ return STATUS_INVALID_PARAMETER_4;
+ }
+
+ /* Enter SEH */
+ _SEH2_TRY
+ {
+ /* Check for user-mode parameters */
+ if (PreviousMode != KernelMode)
{
- /* Probe user pointers */
- ProbeForWriteSize_t(PRegionSize);
- ProbeForWritePointer(PBaseAddress);
+ /* Make sure they are writable */
+ ProbeForWritePointer(UBaseAddress);
+ ProbeForWriteUlong(URegionSize);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Return the exception code */
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
- }
- _SEH2_END;
- }
-
- BaseAddress = (PVOID)PAGE_ROUND_DOWN((*PBaseAddress));
- RegionSize = PAGE_ROUND_UP((ULONG_PTR)(*PBaseAddress) + (*PRegionSize)) -
- PAGE_ROUND_DOWN((*PBaseAddress));
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_OPERATION,
- PsProcessType,
- UserMode,
- (PVOID*)(&Process),
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+
+ /* Capture their values */
+ PBaseAddress = *UBaseAddress;
+ PRegionSize = *URegionSize;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ /* Make sure the allocation isn't past the user area */
+ if (PBaseAddress >= MM_HIGHEST_USER_ADDRESS)
+ {
+ DPRINT1("Virtual free base above User Space\n");
+ return STATUS_INVALID_PARAMETER_2;
+ }
+
+ /* Make sure the allocation wouldn't overflow past the user area */
+ if (((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (ULONG_PTR)PBaseAddress) < PRegionSize)
+ {
+ DPRINT1("Region size would overflow into kernel-memory\n");
+ return STATUS_INVALID_PARAMETER_3;
+ }
+
+ /* Check if this is for the current process */
+ if (ProcessHandle == NtCurrentProcess())
+ {
+ /* We already have the current process, no need to go through Ob */
+ Process = CurrentProcess;
+ }
+ else
+ {
+ /* Reference the handle for correct permissions */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_OPERATION,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&Process,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check if not running in the current process */
+ if (CurrentProcess != Process)
+ {
+ /* Attach to it */
+ KeStackAttachProcess(&Process->Pcb, &ApcState);
+ Attached = TRUE;
+ }
+ }
+
+ BaseAddress = (PVOID)PAGE_ROUND_DOWN((PBaseAddress));
+ RegionSize = PAGE_ROUND_UP((ULONG_PTR)(PBaseAddress) + (PRegionSize)) -
+ PAGE_ROUND_DOWN((PBaseAddress));
AddressSpace = &Process->Vm;
@@ -1372,7 +1451,8 @@
unlock_deref_and_return:
MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
return(Status);
}
Author: sir_richard
Date: Tue Oct 5 15:59:47 2010
New Revision: 49000
URL: http://svn.reactos.org/svn/reactos?rev=49000&view=rev
Log:
[NTOS]: Fix whitespace typo in comment (two spaces instead of one).
That's right. I'm not a fun person.
Modified:
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Tue Oct 5 15:59:47 2010
@@ -250,7 +250,7 @@
#if defined(_X86_)
//
- // Finally, reserve the 2 pages we currently make use of for HAL mappings
+ // Finally, reserve the 2 pages we currently make use of for HAL mappings
//
BaseAddress = (PVOID)0xFFC00000;
Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),