Index: ntoskrnl/mm/ARM3/vadnode.c =================================================================== --- ntoskrnl/mm/ARM3/vadnode.c (revision 57181) +++ ntoskrnl/mm/ARM3/vadnode.c (working copy) @@ -64,7 +64,7 @@ if (!Table->NumberGenericTableElements) return NULL; /* Start looping from the right */ - CurrentNode = RtlRightChildAvl(&Table->BalancedRoot); + CurrentNode = &Table->BalancedRoot; ASSERT(CurrentNode != NULL); while (CurrentNode) { @@ -81,11 +81,18 @@ } else { + /* This address is part of this node, return it */ break; } } + if (CurrentNode) + { + if ((CurrentNode->StartingVpn==0)&&(CurrentNode->EndingVpn==0)) + CurrentNode=NULL; + } + /* Return either the conflicting node, or no node at all */ return CurrentNode; } Index: ntoskrnl/mm/ARM3/virtual.c =================================================================== --- ntoskrnl/mm/ARM3/virtual.c (revision 57181) +++ ntoskrnl/mm/ARM3/virtual.c (working copy) @@ -3458,6 +3458,14 @@ return Status; } +NTSTATUS NTAPI +MmSplitMemoryArea( + PMMSUPPORT AddressSpace, + PVOID BaseAddress, + ULONG_PTR Length, + ULONG AllocationFlags, + BOOLEAN Set + ); /* * @implemented @@ -3675,8 +3683,18 @@ ASSERT((AllocationType & MEM_PHYSICAL) == 0); ASSERT((AllocationType & MEM_WRITE_WATCH) == 0); ASSERT((AllocationType & MEM_TOP_DOWN) == 0); - ASSERT((AllocationType & MEM_RESET) == 0); ASSERT(Process->VmTopDown == 0); + if (AllocationType & MEM_RESET) + { + StartingAddress = (ULONG_PTR)PAGE_ROUND_UP(PBaseAddress);//Increase the address to the next page + EndingAddress = PAGE_ROUND_DOWN((ULONG_PTR)PBaseAddress + PRegionSize ) ;//Reduce the address to the previous page + PRegionSize = EndingAddress - StartingAddress; + AddressSpace = MmGetCurrentAddressSpace(); + MmLockAddressSpace(AddressSpace); + Status=MmSplitMemoryArea(AddressSpace, PBaseAddress,PRegionSize,MEM_RESET,TRUE); + MmUnlockAddressSpace(AddressSpace); + return Status; + } // // Check if the caller is reserving memory, or committing memory and letting Index: ntoskrnl/mm/marea.c =================================================================== --- ntoskrnl/mm/marea.c (revision 57181) +++ ntoskrnl/mm/marea.c (working copy) @@ -442,7 +442,8 @@ if (Depth == 22) { MmRebalanceTree(AddressSpace); - PreviousNode = Node->Parent; + Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + PreviousNode = NULL; } } } @@ -851,7 +852,218 @@ return STATUS_SUCCESS; } +void MmCreateNewMemoryArea(PMEMORY_AREA *MemoryArea, + PMEMORY_AREA Node, + PVOID StartAddress, + PVOID EndAddress, + ULONG AllocationFlags, + BOOLEAN Set + ) +{ + (*MemoryArea)=(PMEMORY_AREA)ExAllocatePoolWithTag(NonPagedPool, + sizeof(MEMORY_AREA), + TAG_MAREA); + RtlZeroMemory((*MemoryArea), sizeof(MEMORY_AREA)); + (*MemoryArea)->Type = Node->Type; + (*MemoryArea)->StartingAddress = StartAddress; + (*MemoryArea)->EndingAddress = EndAddress; + (*MemoryArea)->Protect = Node->Protect; + (*MemoryArea)->Flags =(Set)?Node->Flags|AllocationFlags:Node->Flags&(~AllocationFlags); + (*MemoryArea)->PageOpCount = 0; + (*MemoryArea)->DeleteInProgress = FALSE; + (*MemoryArea)->RightChild=NULL; + (*MemoryArea)->LeftChild=NULL; + (*MemoryArea)->Parent=Node; + (*MemoryArea)->Vad=NULL; + +} +void MmSplitVad( + PMMVAD *Vad, + + PMEMORY_AREA MemoryArea, + PMEMORY_AREA Node + ) +{ + + //VAD + *Vad = (PMMVAD)ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD), TAG_MVAD); + memcpy((Node->Vad),*Vad,sizeof(MMVAD));//Make copy of Vad + + (*Vad)->StartingVpn = PAGE_ROUND_DOWN(MemoryArea->StartingAddress) >> PAGE_SHIFT; + + if (MemoryArea->EndingAddress != MemoryArea->StartingAddress) + { + (*Vad)->EndingVpn = PAGE_ROUND_DOWN((ULONG_PTR)MemoryArea->EndingAddress - 1) >> PAGE_SHIFT; + } + else + { + (*Vad)->EndingVpn = (*Vad)->StartingVpn; + } + + ((PMMVAD)Node->Vad)->StartingVpn = PAGE_ROUND_DOWN(Node->StartingAddress) >> PAGE_SHIFT; + if (Node->EndingAddress != MemoryArea->StartingAddress) + { + ((PMMVAD)Node->Vad)->EndingVpn = PAGE_ROUND_DOWN((ULONG_PTR)Node->EndingAddress - 1) >> PAGE_SHIFT; + } + else + { + ((PMMVAD)Node->Vad)->EndingVpn = ((PMMVAD)Node->Vad)->StartingVpn; + } + (*Vad)->RightChild=NULL; + (*Vad)->LeftChild=NULL; + + MemoryArea->Vad=(*Vad); +} +NTSTATUS NTAPI +MmSplitMemoryArea( + PMMSUPPORT AddressSpace, + PVOID BaseAddress, + + ULONG_PTR Length, + + ULONG AllocationFlags, + BOOLEAN Set + ) + +{ + while (TRUE) + { + PMEMORY_AREA MemoryArea; + PMEMORY_AREA Node = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)PAGE_ROUND_DOWN(BaseAddress)); + if (Node==NULL) + return STATUS_NO_MEMORY; + PVOID StartAddress; + PVOID EndAddress; + + StartAddress=(PVOID)PAGE_ROUND_UP(BaseAddress); + EndAddress=(PVOID)PAGE_ROUND_UP((PVOID)((ULONG_PTR)StartAddress+Length)); + EndAddress=(EndAddress<=Node->EndingAddress)?EndAddress:Node->EndingAddress; + + MEMORY_AREA Old=*Node; + + + if (StartAddress==Node->StartingAddress) + { + if (EndAddress==Node->EndingAddress)//if select==area + { + Node->Flags=(Set)?Old.Flags|AllocationFlags:Old.Flags&(~AllocationFlags); + + + + if (((ULONG_PTR)StartAddress+Length)==(ULONG_PTR)EndAddress)//Other section? + return STATUS_SUCCESS; + + } + else if (EndAddressEndingAddress)//if select enter in one area + { + + MmCreateNewMemoryArea(&MemoryArea, + Node, + StartAddress, + EndAddress, + AllocationFlags, + Set); + Node->StartingAddress=EndAddress; + MemoryArea->LeftChild=Node->LeftChild; + Node->LeftChild=MemoryArea; + if(Old.LeftChild) + Old.LeftChild->Parent=MemoryArea; + if (Node->Vad) + { + PMMVAD Vad; + MmSplitVad(&Vad, + MemoryArea, + Node); + Vad->LeftChild=((PMMVAD)Node->Vad)->LeftChild; + ((PMMVAD)Node->Vad)->LeftChild=Vad; + } + + return STATUS_SUCCESS; + } + }else + { + if (EndAddress==Node->EndingAddress)//if select==area + { + + MmCreateNewMemoryArea(&MemoryArea, + Node, + StartAddress, + EndAddress, + AllocationFlags, + Set); + Node->EndingAddress=StartAddress; + MemoryArea->RightChild=Node->RightChild; + Node->RightChild=MemoryArea; + if(Old.RightChild) + Old.RightChild->Parent=MemoryArea; + if (Node->Vad) + { + PMMVAD Vad; + MmSplitVad(&Vad, + MemoryArea, + Node); + Vad->RightChild=((PMMVAD)Node->Vad)->RightChild; + ((PMMVAD)Node->Vad)->RightChild=Vad; + } + + + + if (((ULONG_PTR)StartAddress+Length)==(ULONG_PTR)EndAddress)//Other section? + return STATUS_SUCCESS; + } + else if (EndAddressEndingAddress)//if select enter in one area + { + MmCreateNewMemoryArea(&MemoryArea, + Node, + StartAddress, + EndAddress, + AllocationFlags, + Set); + Node->EndingAddress=StartAddress; + MemoryArea->RightChild=Node->RightChild; + Node->RightChild=MemoryArea; + if(Old.RightChild) + Old.RightChild->Parent=MemoryArea; + PMMVAD Vad; + + if (Node->Vad) + { + MmSplitVad(&Vad, + MemoryArea, + Node); + Vad->RightChild=((PMMVAD)Node->Vad)->RightChild; + ((PMMVAD)Node->Vad)->RightChild=Vad; + + } + Node=MemoryArea; + MmCreateNewMemoryArea(&MemoryArea, + Node, + EndAddress, + Old.EndingAddress, + AllocationFlags, + !Set); + MemoryArea->RightChild=Node->RightChild; + Node->RightChild=MemoryArea; + if(Old.RightChild) + Old.RightChild->Parent=MemoryArea; + if (Node->Vad) + { + MmSplitVad(&Vad, + MemoryArea, + Node); + Vad->RightChild=((PMMVAD)Node->Vad)->RightChild; + ((PMMVAD)Node->Vad)->RightChild=Vad; + } + + + return STATUS_SUCCESS; + } + } + DPRINT1("6\n"); + BaseAddress=Node->EndingAddress; + } +} /** * @name MmCreateMemoryArea *