/* Include Mm version of AVL support */
#include "miavl.h"
-#include <lib/rtl/avlsupp.c>
+#include <sdk/lib/rtl/avlsupp.c>
/* GLOBALS ********************************************************************/
PVOID AllocatedBase = (PVOID)(Vad->StartingVpn << PAGE_SHIFT);
Size = ((Vad->EndingVpn + 1) - Vad->StartingVpn) << PAGE_SHIFT;
+
+ if (AllocatedBase == NULL)
+ {
+ AllocatedBase = (PVOID)(ULONG_PTR)1;
+ Size -= 1;
+ }
+
Status = MmCreateMemoryArea(&Process->Vm,
MEMORY_AREA_OWNED_BY_ARM3,
&AllocatedBase,
Size,
PAGE_READWRITE,
&MemoryArea,
- TRUE,
0,
PAGE_SIZE);
ASSERT(NT_SUCCESS(Status));
else
{
/* This is a section VAD. Store the MAREA here for now */
- ASSERT(Vad->u4.Banked == (PVOID)0xDEADBABE);
+ ASSERT(Vad->u4.Banked == (PVOID)(ULONG_PTR)0xDEADBABEDEADBABEULL);
Vad->u4.Banked = (PVOID)MemoryArea;
}
}
VOID
NTAPI
MiInsertVad(IN PMMVAD Vad,
- IN PEPROCESS Process)
+ IN PMM_AVL_TABLE VadRoot)
{
TABLE_SEARCH_RESULT Result;
PMMADDRESS_NODE Parent = NULL;
/* Validate the VAD and set it as the current hint */
ASSERT(Vad->EndingVpn >= Vad->StartingVpn);
- Process->VadRoot.NodeHint = Vad;
+ VadRoot->NodeHint = Vad;
/* Find the parent VAD and where this child should be inserted */
- Result = RtlpFindAvlTableNodeOrParent(&Process->VadRoot, (PVOID)Vad->StartingVpn, &Parent);
+ Result = RtlpFindAvlTableNodeOrParent(VadRoot, (PVOID)Vad->StartingVpn, &Parent);
ASSERT(Result != TableFoundNode);
ASSERT((Parent != NULL) || (Result == TableEmptyTree));
/* Do the actual insert operation */
- MiLockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread());
- MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result);
- MiUnlockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread());
+ MiInsertNode(VadRoot, (PVOID)Vad, Parent, Result);
}
NTSTATUS
&Parent);
if (Result == TableFoundNode)
{
- DPRINT1("Given address conflicts with existing node\n");
+ DPRINT("Given address conflicts with existing node\n");
KeReleaseGuardedMutex(&CurrentProcess->AddressCreationLock);
return STATUS_CONFLICTING_ADDRESSES;
}
/* Free the node from ReactOS view as well */
Vad = (PMMVAD_LONG)Node;
- if (Vad->u.VadFlags.Spare == 0)
+ if ((Table != &MmSectionBasedRoot) && (Vad->u.VadFlags.Spare == 0))
{
PMEMORY_AREA MemoryArea;
PEPROCESS Process;
if (MemoryArea)
{
/* Make sure we have not already freed it */
- ASSERT(MemoryArea != (PVOID)0xDEADBAB1);
+ ASSERT(MemoryArea != (PVOID)(ULONG_PTR)0xDEADBAB1DEADBAB1ULL);
/* Get the process */
Process = CONTAINING_RECORD(Table, EPROCESS, VadRoot);
if (Vad->ControlArea == NULL)
{
/* Delete the pointer to it */
- Vad->FirstPrototypePte = (PVOID)0xDEADBAB1;
+ Vad->FirstPrototypePte = (PVOID)(ULONG_PTR)0xDEADBAB1DEADBAB1ULL;
}
else
{
/* Delete the pointer to it */
- Vad->u4.Banked = (PVOID)0xDEADBAB1;
+ Vad->u4.Banked = (PVOID)(ULONG_PTR)0xDEADBAB1DEADBAB1ULL;
}
}
}
OUT PULONG_PTR Base)
{
PMMADDRESS_NODE Node, PreviousNode;
- ULONG_PTR PageCount, AlignmentVpn, LowVpn, HighVpn;
+ ULONG_PTR PageCount, AlignmentVpn, LowVpn, HighestVpn;
ASSERT(Length != 0);
/* Calculate page numbers for the length, alignment, and starting address */
AlignmentVpn = Alignment >> PAGE_SHIFT;
LowVpn = ALIGN_UP_BY((ULONG_PTR)MM_LOWEST_USER_ADDRESS >> PAGE_SHIFT, AlignmentVpn);
+ /* Check for kernel mode table (memory areas) */
+ if (Table->Unused == 1)
+ {
+ LowVpn = ALIGN_UP_BY((ULONG_PTR)MmSystemRangeStart >> PAGE_SHIFT, AlignmentVpn);
+ }
+
/* Check if the table is empty */
if (Table->NumberGenericTableElements == 0)
{
}
/* We're up to the highest VAD, will this allocation fit above it? */
- HighVpn = ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) / PAGE_SIZE;
- if (HighVpn >= LowVpn + PageCount)
+ HighestVpn = ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) / PAGE_SIZE;
+
+ /* Check for kernel mode table (memory areas) */
+ if (Table->Unused == 1)
+ {
+ HighestVpn = ALIGN_UP_BY((ULONG_PTR)(LONG_PTR)-1 >> PAGE_SHIFT, AlignmentVpn);
+ }
+
+ if (HighestVpn >= LowVpn + PageCount)
{
/* Yes! Use this VAD to store the allocation */
*PreviousVad = PreviousNode;
OUT PULONG_PTR Base,
OUT PMMADDRESS_NODE *Parent)
{
- PMMADDRESS_NODE Node, OldNode, Child;
+ PMMADDRESS_NODE Node, OldNode = NULL, Child;
ULONG_PTR LowVpn, HighVpn, AlignmentVpn;
PFN_NUMBER PageCount;
PageCount = Length >> PAGE_SHIFT;
AlignmentVpn = Alignment / PAGE_SIZE;
+ /* Check for kernel mode table (memory areas) */
+ if (Table->Unused == 1)
+ {
+ LowVpn = ALIGN_UP_BY((ULONG_PTR)MmSystemRangeStart >> PAGE_SHIFT, AlignmentVpn);
+ }
+ else
+ {
+ LowVpn = ALIGN_UP_BY((ULONG_PTR)MM_LOWEST_USER_ADDRESS, Alignment);
+ }
+
/* Check if there is enough space below the boundary */
- if ((ALIGN_UP_BY((ULONG_PTR)MM_LOWEST_USER_ADDRESS, Alignment) + Length) >
- (BoundaryAddress + 1))
+ if ((LowVpn + Length) > (BoundaryAddress + 1))
{
return TableFoundNode;
}
}
else
{
- /* Node has a right child, the node we had before is the most
- left grandchild of that right child, use it as parent. */
+ /* Node has a right child. This means we must have already
+ moved one node left from the right-most node we started
+ with, thus we already have an OldNode! */
+ ASSERT(OldNode != NULL);
+
+ /* The node we had before is the most left grandchild of
+ that right child, use it as parent. */
+ ASSERT(RtlLeftChildAvl(OldNode) == NULL);
*Parent = OldNode;
return TableInsertAsLeft;
}