Index: ntoskrnl/mm/ARM3/miarm.h =================================================================== --- ntoskrnl/mm/ARM3/miarm.h (revision 62466) +++ ntoskrnl/mm/ARM3/miarm.h (working copy) @@ -2093,42 +2093,43 @@ IN PVOID VirtualAddress ); -PMMADDRESS_NODE +TABLE_SEARCH_RESULT NTAPI MiCheckForConflictingNode( - IN ULONG_PTR StartVpn, - IN ULONG_PTR EndVpn, - IN PMM_AVL_TABLE Table + _In_ PMM_AVL_TABLE Table, + _In_ ULONG_PTR StartingVpn, + _In_ ULONG_PTR EndingVpn, + _Out_ PMMADDRESS_NODE *NodeOrParent ); TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeDownTree( - IN SIZE_T Length, - IN ULONG_PTR BoundaryAddress, - IN ULONG_PTR Alignment, - IN PMM_AVL_TABLE Table, - OUT PULONG_PTR Base, - OUT PMMADDRESS_NODE *Parent + _In_ PMM_AVL_TABLE Table, + _In_ SIZE_T Length, + _In_ ULONG_PTR BoundaryAddress, + _In_ ULONG_PTR Alignment, + _Out_ PULONG_PTR Base, + _Out_ PMMADDRESS_NODE *Parent ); -NTSTATUS +TABLE_SEARCH_RESULT NTAPI -MiFindEmptyAddressRangeDownBasedTree( - IN SIZE_T Length, - IN ULONG_PTR BoundaryAddress, - IN ULONG_PTR Alignment, - IN PMM_AVL_TABLE Table, - OUT PULONG_PTR Base +MiFindEmptyAddressRangeInTree( + _In_ PMM_AVL_TABLE Table, + _In_ SIZE_T Length, + _In_ ULONG_PTR Alignment, + _Out_ PULONG_PTR Base, + _Out_ PMMADDRESS_NODE *Parent ); NTSTATUS NTAPI -MiFindEmptyAddressRangeInTree( +MiFindEmptyAddressRangeDownBasedTree( IN SIZE_T Length, + IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, - OUT PMMADDRESS_NODE *PreviousVad, OUT PULONG_PTR Base ); Index: ntoskrnl/mm/ARM3/procsup.c =================================================================== --- ntoskrnl/mm/ARM3/procsup.c (revision 62466) +++ ntoskrnl/mm/ARM3/procsup.c (working copy) @@ -97,10 +97,10 @@ EndAddress = StartAddress + ROUND_TO_PAGES(Size) - 1; /* Try to find something below the random upper margin */ - Result = MiFindEmptyAddressRangeDownTree(ROUND_TO_PAGES(Size), + Result = MiFindEmptyAddressRangeDownTree(&Process->VadRoot, + ROUND_TO_PAGES(Size), EndAddress, PAGE_SIZE, - &Process->VadRoot, Base, &Parent); } @@ -109,10 +109,10 @@ if (Result == TableFoundNode) { /* For TEBs, or if a PEB location couldn't be found, scan the VAD root */ - Result = MiFindEmptyAddressRangeDownTree(ROUND_TO_PAGES(Size), + Result = MiFindEmptyAddressRangeDownTree(&Process->VadRoot, + ROUND_TO_PAGES(Size), (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1, PAGE_SIZE, - &Process->VadRoot, Base, &Parent); /* Bail out, if still nothing free was found */ Index: ntoskrnl/mm/ARM3/section.c =================================================================== --- ntoskrnl/mm/ARM3/section.c (revision 62466) +++ ntoskrnl/mm/ARM3/section.c (working copy) @@ -1214,6 +1214,8 @@ ULONG QuotaCharge = 0, QuotaExcess = 0; PMMPTE PointerPte, LastPte; MMPTE TempPte; + PMMADDRESS_NODE Parent; + TABLE_SEARCH_RESULT Result; /* Get the segment for this section */ Segment = ControlArea->Segment; @@ -1302,25 +1304,29 @@ if (AllocationType & MEM_TOP_DOWN) { /* No, find an address top-down */ - Status = MiFindEmptyAddressRangeDownTree(*ViewSize, + Result = MiFindEmptyAddressRangeDownTree(&Process->VadRoot, + *ViewSize, (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS, _64K, - &Process->VadRoot, &StartAddress, - (PMMADDRESS_NODE*)&Process->VadFreeHint); - ASSERT(NT_SUCCESS(Status)); + &Parent); } else { /* No, find an address bottom-up */ - Status = MiFindEmptyAddressRangeInTree(*ViewSize, + Result = MiFindEmptyAddressRangeInTree(&Process->VadRoot, + *ViewSize, _64K, - &Process->VadRoot, - (PMMADDRESS_NODE*)&Process->VadFreeHint, - &StartAddress); - ASSERT(NT_SUCCESS(Status)); + &StartAddress, + &Parent); } + /* Check if we found a suitable location */ + if (Result == TableFoundNode) + { + ASSERT(FALSE); + } + /* Get the ending address, which is the last piece we need for the VAD */ EndingAddress = (StartAddress + *ViewSize - 1) | (PAGE_SIZE - 1); } @@ -1343,9 +1349,11 @@ EndingAddress = (StartAddress + *ViewSize - 1) | (PAGE_SIZE - 1); /* Make sure it doesn't conflict with an existing allocation */ - if (MiCheckForConflictingNode(StartAddress >> PAGE_SHIFT, - EndingAddress >> PAGE_SHIFT, - &Process->VadRoot)) + Result = MiCheckForConflictingNode(&Process->VadRoot, + StartAddress >> PAGE_SHIFT, + EndingAddress >> PAGE_SHIFT, + &Parent); + if (Result == TableFoundNode) { DPRINT1("Conflict with SEC_BASED or manually based section!\n"); MiDereferenceControlArea(ControlArea); @@ -1395,7 +1403,8 @@ MiLockProcessWorkingSetUnsafe(Process, Thread); /* Insert the VAD */ - MiInsertVad((PMMVAD)Vad, Process); + Process->VadRoot.NodeHint = Vad; + MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); /* Release the working set */ MiUnlockProcessWorkingSetUnsafe(Process, Thread); Index: ntoskrnl/mm/ARM3/vadnode.c =================================================================== --- ntoskrnl/mm/ARM3/vadnode.c (revision 62466) +++ ntoskrnl/mm/ARM3/vadnode.c (working copy) @@ -73,42 +73,59 @@ return FoundVad; } -PMMADDRESS_NODE +TABLE_SEARCH_RESULT NTAPI -MiCheckForConflictingNode(IN ULONG_PTR StartVpn, - IN ULONG_PTR EndVpn, - IN PMM_AVL_TABLE Table) +MiCheckForConflictingNode( + _In_ PMM_AVL_TABLE Table, + _In_ ULONG_PTR StartingVpn, + _In_ ULONG_PTR EndingVpn, + _Out_ PMMADDRESS_NODE *NodeOrParent) { - PMMADDRESS_NODE CurrentNode; + PMMADDRESS_NODE CurrentNode, ChildNode; /* If the tree is empty, there is no conflict */ - if (!Table->NumberGenericTableElements) return NULL; + if (Table->NumberGenericTableElements == 0) + { + return TableEmptyTree; + } - /* Start looping from the right */ - CurrentNode = RtlRightChildAvl(&Table->BalancedRoot); - ASSERT(CurrentNode != NULL); - while (CurrentNode) + /* Start looping from the root node */ + ChildNode = RtlRightChildAvl(&Table->BalancedRoot); + ASSERT(ChildNode != NULL); + do { + CurrentNode = ChildNode; + /* This address comes after */ - if (StartVpn > CurrentNode->EndingVpn) + if (StartingVpn > CurrentNode->EndingVpn) { /* Keep searching on the right */ - CurrentNode = RtlRightChildAvl(CurrentNode); + ChildNode = RtlRightChildAvl(CurrentNode); } - else if (EndVpn < CurrentNode->StartingVpn) + else if (EndingVpn < CurrentNode->StartingVpn) { /* This address ends before the node starts, search on the left */ - CurrentNode = RtlLeftChildAvl(CurrentNode); + ChildNode = RtlLeftChildAvl(CurrentNode); } else { /* This address is part of this node, return it */ - break; + *NodeOrParent = CurrentNode; + return TableFoundNode; } } + while (ChildNode); - /* Return either the conflicting node, or no node at all */ - return CurrentNode; + /* There is no more child, save the current node as parent */ + *NodeOrParent = CurrentNode; + if (StartingVpn > CurrentNode->EndingVpn) + { + return TableInsertAsRight; + } + else + { + return TableInsertAsLeft; + } } VOID @@ -338,135 +355,152 @@ return NULL; } -NTSTATUS +TABLE_SEARCH_RESULT NTAPI -MiFindEmptyAddressRangeInTree(IN SIZE_T Length, - IN ULONG_PTR Alignment, - IN PMM_AVL_TABLE Table, - OUT PMMADDRESS_NODE *PreviousVad, - OUT PULONG_PTR Base) +MiFindEmptyAddressRangeInTree( + _In_ PMM_AVL_TABLE Table, + _In_ SIZE_T Length, + _In_ ULONG_PTR Alignment, + _Out_ PULONG_PTR Base, + _Out_ PMMADDRESS_NODE *Parent) { - PMMADDRESS_NODE Node; - PMMADDRESS_NODE NextNode; - ULONG_PTR StartingVpn, HighestVpn, AlignmentVpn, LengthVpn, LowVpn; + PMMADDRESS_NODE Node, PreviousNode;//, Child; + ULONG_PTR PageCount, AlignmentVpn, LowVpn, HighVpn; ASSERT(Length != 0); - /* Precompute page numbers for the length, alignment, and starting address */ - LengthVpn = (Length + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - AlignmentVpn = Alignment >> PAGE_SHIFT; - StartingVpn = ROUND_UP((ULONG_PTR)MM_LOWEST_USER_ADDRESS >> PAGE_SHIFT, - AlignmentVpn); + /* Calculate page numbers for the length, alignment, and starting address */ + PageCount = BYTES_TO_PAGES(Length); + AlignmentVpn = Alignment / PAGE_SIZE; + LowVpn = ALIGN_UP_BY((ULONG_PTR)MM_LOWEST_USER_ADDRESS / PAGE_SIZE, AlignmentVpn); - /* Check if the table is free, so the lowest possible address is available */ - if (!Table->NumberGenericTableElements) goto FoundAtBottom; + /* Check if the table is empty */ + if (Table->NumberGenericTableElements == 0) + { + /* Tree is empty, the candidate address is already the best one */ + *Base = LowVpn << PAGE_SHIFT; + return TableEmptyTree; + } /* Otherwise, follow the leftmost child of the right root node's child */ Node = RtlRightChildAvl(&Table->BalancedRoot); while (RtlLeftChildAvl(Node)) Node = RtlLeftChildAvl(Node); - /* This is the node for the remaining gap at the bottom, can it be used? */ - if ((Node->StartingVpn > StartingVpn) && - (LengthVpn < Node->StartingVpn - StartingVpn)) + /* Start a search to find a gap */ + PreviousNode = NULL; + while (Node != NULL) { -FoundAtBottom: - /* Use this VAD to store the allocation */ - *PreviousVad = NULL; - *Base = StartingVpn << PAGE_SHIFT; - return STATUS_SUCCESS; - } + /* Check if the gap below the current node is suitable */ + if (Node->StartingVpn >= LowVpn + PageCount) + { + /* There is enough space to add our node */ + *Base = LowVpn << PAGE_SHIFT; - /* Otherwise, we start a search to find a gap */ - while (TRUE) - { - /* The last aligned page number in this entry */ - LowVpn = ROUND_UP(Node->EndingVpn + 1, AlignmentVpn); + /* Can we use the current node as parent? */ + if (RtlLeftChildAvl(Node) == NULL) + { + /* Node has no left child, so use it as parent */ + *Parent = Node; + return TableInsertAsLeft; + } + else + { + /* Node has a left child, this means that the previous node is + the right-most child of it's left child and can be used as + the parent. In case we use the space before the left-most + node, it's left child must be NULL. */ + NT_ASSERT(PreviousNode != NULL); + NT_ASSERT(RtlRightChildAvl(PreviousNode) == NULL); + *Parent = PreviousNode; + return TableInsertAsRight; + } + } - /* Keep going as long as there's still a next node */ - NextNode = MiGetNextNode(Node); - if (!NextNode) break; + /* The next candidate is above the current node */ + if (Node->EndingVpn >= LowVpn) + LowVpn = ALIGN_UP_BY(Node->EndingVpn + 1, AlignmentVpn); - /* Can this allocation fit in this node? */ - if ((LengthVpn <= (NextNode->StartingVpn - LowVpn)) && - (NextNode->StartingVpn > LowVpn)) - { -Found: - /* Yes! Use this VAD to store the allocation */ - *PreviousVad = Node; - *Base = ROUND_UP((Node->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1), - Alignment); - return STATUS_SUCCESS; - } + /* Remember the current node and go to the next node */ + PreviousNode = Node; + Node = MiGetNextNode(Node); + } - /* Try the next node */ - Node = NextNode; + /* 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) + { + /* Yes! Use this VAD to store the allocation */ + *Parent = PreviousNode; + *Base = LowVpn << PAGE_SHIFT; + return TableInsertAsRight; } - /* We're down to the last (top) VAD, will this allocation fit inside it? */ - HighestVpn = ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) >> PAGE_SHIFT; - if ((HighestVpn > LowVpn) && (LengthVpn <= HighestVpn - LowVpn)) goto Found; - /* Nyet, there's no free address space for this allocation, so we'll fail */ - return STATUS_NO_MEMORY; + return TableFoundNode; } TABLE_SEARCH_RESULT NTAPI -MiFindEmptyAddressRangeDownTree(IN SIZE_T Length, - IN ULONG_PTR BoundaryAddress, - IN ULONG_PTR Alignment, - IN PMM_AVL_TABLE Table, - OUT PULONG_PTR Base, - OUT PMMADDRESS_NODE *Parent) +MiFindEmptyAddressRangeDownTree( + _In_ PMM_AVL_TABLE Table, + _In_ SIZE_T Length, + _In_ ULONG_PTR BoundaryAddress, + _In_ ULONG_PTR Alignment, + _Out_ PULONG_PTR Base, + _Out_ PMMADDRESS_NODE *Parent) { - PMMADDRESS_NODE Node, LowestNode, Child; - ULONG_PTR LowVpn, HighVpn; + PMMADDRESS_NODE Node, OldNode, Child; + ULONG_PTR LowVpn, HighVpn, AlignmentVpn; PFN_NUMBER PageCount; /* Sanity checks */ ASSERT(BoundaryAddress); ASSERT(BoundaryAddress <= ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); + ASSERT((Alignment & (PAGE_SIZE - 1)) == 0); - /* Compute page length, make sure the boundary address is valid */ + /* Calculate page numbers for the length and alignment */ Length = ROUND_TO_PAGES(Length); PageCount = Length >> PAGE_SHIFT; - if ((BoundaryAddress + 1) < Length) return TableFoundNode; + AlignmentVpn = Alignment / PAGE_SIZE; + /* Check if there is enough space below the boundary */ + if ((ALIGN_UP_BY((ULONG_PTR)MM_LOWEST_USER_ADDRESS, Alignment) + Length) > + (BoundaryAddress + 1)) + { + return TableFoundNode; + } + /* Check if the table is empty */ if (Table->NumberGenericTableElements == 0) { /* Tree is empty, the candidate address is already the best one */ - *Base = ROUND_UP(BoundaryAddress + 1 - Length, Alignment); + *Base = ALIGN_DOWN_BY(BoundaryAddress + 1 - Length, Alignment); return TableEmptyTree; } /* Calculate the initial upper margin */ - HighVpn = BoundaryAddress >> PAGE_SHIFT; + HighVpn = (BoundaryAddress + 1) >> PAGE_SHIFT; - /* Starting from the root, go down until the right-most child - * which is just behind the boundary*/ - LowestNode = Node = RtlRightChildAvl(&Table->BalancedRoot); - while (((Child = RtlRightChildAvl(Node)) != 0 ) - && (Node->EndingVpn < HighVpn )) Node = Child; + /* Starting from the root, follow the right children until we found a node + that ends above the boundary */ + Node = RtlRightChildAvl(&Table->BalancedRoot); + while ((Node->EndingVpn < HighVpn) && + ((Child = RtlRightChildAvl(Node)) != NULL)) Node = Child; /* Now loop the Vad nodes */ while (Node) { - /* Keep track of the lowest node */ - LowestNode = Node; - /* Calculate the lower margin */ - LowVpn = ROUND_UP(Node->EndingVpn + 1, Alignment >> PAGE_SHIFT); + LowVpn = ALIGN_UP_BY(Node->EndingVpn + 1, AlignmentVpn); /* Check if the current bounds are suitable */ if ((HighVpn > LowVpn) && ((HighVpn - LowVpn) >= PageCount)) { /* There is enough space to add our node */ - LowVpn = HighVpn - PageCount; + LowVpn = ALIGN_DOWN_BY(HighVpn - PageCount, AlignmentVpn); *Base = LowVpn << PAGE_SHIFT; /* Can we use the current node as parent? */ - Child = RtlRightChildAvl(Node); - if (!Child) + if (!RtlRightChildAvl(Node)) { /* Node has no right child, so use it as parent */ *Parent = Node; @@ -474,29 +508,29 @@ } else { - /* Node has a right child, find most left grand child */ - Node = Child; - while ((Child = RtlLeftChildAvl(Node))) Node = Child; - *Parent = Node; + /* Node has a right child, the node we had before is the most + left grandchild of that right child, use it as parent. */ + *Parent = OldNode; return TableInsertAsLeft; } } - /* Update the upper margin if neccessary */ + /* Update the upper margin if necessary */ if (Node->StartingVpn < HighVpn) HighVpn = Node->StartingVpn; - /* Go to the next lower node */ + /* Remember the current node and go to the previous node */ + OldNode = Node; Node = MiGetPreviousNode(Node); } /* Check if there's enough space before the lowest Vad */ - LowVpn = ROUND_UP((ULONG_PTR)MI_LOWEST_VAD_ADDRESS, Alignment) >> PAGE_SHIFT; + LowVpn = ALIGN_UP_BY((ULONG_PTR)MI_LOWEST_VAD_ADDRESS, Alignment) / PAGE_SIZE; if ((HighVpn > LowVpn) && ((HighVpn - LowVpn) >= PageCount)) { /* There is enough space to add our address */ - LowVpn = HighVpn - PageCount; + LowVpn = ALIGN_DOWN_BY(HighVpn - PageCount, Alignment >> PAGE_SHIFT); *Base = LowVpn << PAGE_SHIFT; - *Parent = LowestNode; + *Parent = OldNode; return TableInsertAsLeft; } @@ -506,6 +540,11 @@ return TableFoundNode; } +/* Note: We have this extra function, that basically does the same thing as + MiFindEmptyAddressRangeDownTree, simply because someone thought it was + a cool idea to store absolute addresses rather than VPNs in the section tree. + And obviously at MS they prefer to copy large chunks of code, rather than + rethinking their design. For now we keep this for "compatibility"... */ NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree(IN SIZE_T Length, @@ -527,7 +566,7 @@ if ((BoundaryAddress + 1) < Length) return STATUS_NO_MEMORY; /* Check if the table is empty */ - BestVpn = ROUND_UP(BoundaryAddress + 1 - Length, Alignment); + BestVpn = ROUND_DOWN(BoundaryAddress + 1 - Length, Alignment); if (Table->NumberGenericTableElements == 0) { /* Tree is empty, the candidate address is already the best one */ @@ -540,11 +579,11 @@ while (RtlRightChildAvl(Node)) Node = RtlRightChildAvl(Node); /* Check if we can fit in here */ - LowVpn = ROUND_UP(Node->EndingVpn, Alignment); + LowVpn = ROUND_UP(Node->EndingVpn + 1, Alignment); if ((LowVpn < BoundaryAddress) && (Length < (BoundaryAddress - LowVpn))) { /* Return the address */ - *Base = ROUND_UP(BoundaryAddress - Length, Alignment); + *Base = BestVpn; return STATUS_SUCCESS; } @@ -558,11 +597,11 @@ /* Check if this node could contain the requested address */ LowVpn = ROUND_UP(LowestNode->EndingVpn + 1, Alignment); if ((LowestNode->EndingVpn < BestVpn) && + (LowVpn < Node->StartingVpn) && (Length <= (Node->StartingVpn - LowVpn))) { /* Check if it fits in perfectly */ - if ((BestVpn > LowestNode->EndingVpn) && - (BoundaryAddress < Node->StartingVpn)) + if (BoundaryAddress < Node->StartingVpn) { /* Return the optimal VPN address */ *Base = BestVpn; @@ -669,3 +708,4 @@ } /* EOF */ + Index: ntoskrnl/mm/ARM3/virtual.c =================================================================== --- ntoskrnl/mm/ARM3/virtual.c (revision 62482) +++ ntoskrnl/mm/ARM3/virtual.c (working copy) @@ -1903,6 +1903,7 @@ BOOLEAN Committed; NTSTATUS Status = STATUS_SUCCESS; PETHREAD Thread = PsGetCurrentThread(); + TABLE_SEARCH_RESULT Result; /* Calculate base address for the VAD */ StartingAddress = (ULONG_PTR)PAGE_ALIGN((*BaseAddress)); @@ -1939,10 +1940,11 @@ } /* Get the VAD for this address range, and make sure it exists */ - Vad = (PMMVAD)MiCheckForConflictingNode(StartingAddress >> PAGE_SHIFT, - EndingAddress >> PAGE_SHIFT, - &Process->VadRoot); - if (!Vad) + Result = MiCheckForConflictingNode(&Process->VadRoot, + StartingAddress >> PAGE_SHIFT, + EndingAddress >> PAGE_SHIFT, + (PMMADDRESS_NODE*)&Vad); + if (Result != TableFoundNode) { DPRINT("Could not find a VAD for this allocation\n"); Status = STATUS_CONFLICTING_ADDRESSES; @@ -4099,6 +4101,8 @@ BOOLEAN Attached = FALSE, ChangeProtection = FALSE; MMPTE TempPte; PMMPTE PointerPte, PointerPde, LastPte; + TABLE_SEARCH_RESULT Result; + PMMADDRESS_NODE Parent; PAGED_CODE(); /* Check for valid Zero bits */ @@ -4384,13 +4388,29 @@ // if (!PBaseAddress) { - Status = MiFindEmptyAddressRangeInTree(PRegionSize, - _64K, - &Process->VadRoot, - (PMMADDRESS_NODE*)&Process->VadFreeHint, - &StartingAddress); - if (!NT_SUCCESS(Status)) goto FailPath; + /* Which way should we search? */ + if (AllocationType & MEM_TOP_DOWN) + { + /* Find an address top-down */ + Result = MiFindEmptyAddressRangeDownTree(&Process->VadRoot, + PRegionSize, + (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS, + _64K, + &StartingAddress, + &Parent); + } + else + { + /* Find an address bottom-up */ + Result = MiFindEmptyAddressRangeInTree(&Process->VadRoot, + PRegionSize, + _64K, + &StartingAddress, + &Parent); + } + if (Result == TableFoundNode) goto FailPath; + // // Now we know where the allocation ends. Make sure it doesn't end up // somewhere in kernel mode. @@ -4402,15 +4422,21 @@ goto FailPath; } } - else if (MiCheckForConflictingNode(StartingAddress >> PAGE_SHIFT, - EndingAddress >> PAGE_SHIFT, - &Process->VadRoot)) + else { - // - // The address specified is in conflict! - // - Status = STATUS_CONFLICTING_ADDRESSES; - goto FailPath; + /* Make sure it doesn't conflict with an existing allocation */ + Result = MiCheckForConflictingNode(&Process->VadRoot, + StartingAddress >> PAGE_SHIFT, + EndingAddress >> PAGE_SHIFT, + &Parent); + if (Result == TableFoundNode) + { + // + // The address specified is in conflict! + // + Status = STATUS_CONFLICTING_ADDRESSES; + goto FailPath; + } } // @@ -4429,7 +4455,8 @@ // MiLockProcessWorkingSetUnsafe(Process, CurrentThread); Vad->ControlArea = NULL; // For Memory-Area hack - MiInsertVad(Vad, Process); + Process->VadRoot.NodeHint = Vad; + MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread); // @@ -4495,10 +4522,11 @@ // // Get the VAD for this address range, and make sure it exists // - FoundVad = (PMMVAD)MiCheckForConflictingNode(StartingAddress >> PAGE_SHIFT, - EndingAddress >> PAGE_SHIFT, - &Process->VadRoot); - if (!FoundVad) + Result = MiCheckForConflictingNode(&Process->VadRoot, + StartingAddress >> PAGE_SHIFT, + EndingAddress >> PAGE_SHIFT, + (PMMADDRESS_NODE*)&FoundVad); + if (Result != TableFoundNode) { DPRINT1("Could not find a VAD for this allocation\n"); Status = STATUS_CONFLICTING_ADDRESSES;