/* Check the previous node and merge if possible */
if (PrevNode->pVirtualBlock + PrevNode->nVirtualBlockSize == Node->pVirtualBlock)
{
- /* They are adjacent - merge! */
- PrevNode->nVirtualBlockSize += Node->nVirtualBlockSize;
- RtlpDphReturnNodeToUnusedList(DphRoot, Node);
- DphRoot->nAvailableAllocations--;
+ /* Check they actually belong to the same virtual memory block */
+ NTSTATUS Status;
+ MEMORY_BASIC_INFORMATION MemoryBasicInfo;
+
+ Status = ZwQueryVirtualMemory(
+ ZwCurrentProcess(),
+ Node->pVirtualBlock,
+ MemoryBasicInformation,
+ &MemoryBasicInfo,
+ sizeof(MemoryBasicInfo),
+ NULL);
+
+ /* There is no way this can fail, we committed this memory! */
+ ASSERT(NT_SUCCESS(Status));
+
+ if ((PUCHAR)MemoryBasicInfo.AllocationBase <= PrevNode->pVirtualBlock)
+ {
+ /* They are adjacent, and from the same VM region. - merge! */
+ PrevNode->nVirtualBlockSize += Node->nVirtualBlockSize;
+ RtlpDphReturnNodeToUnusedList(DphRoot, Node);
+ DphRoot->nAvailableAllocations--;
- Node = PrevNode;
+ Node = PrevNode;
+ }
+ else
+ {
+ /* Insert after PrevNode */
+ InsertTailList(&PrevNode->AvailableEntry, &Node->AvailableEntry);
+ }
}
else
{
/* Node is not at the tail of the list, check if it's adjacent */
if (Node->pVirtualBlock + Node->nVirtualBlockSize == NextNode->pVirtualBlock)
{
- /* They are adjacent - merge! */
- Node->nVirtualBlockSize += NextNode->nVirtualBlockSize;
-
- /* Remove next entry from the list and put it into unused entries list */
- RemoveEntryList(&NextNode->AvailableEntry);
- RtlpDphReturnNodeToUnusedList(DphRoot, NextNode);
- DphRoot->nAvailableAllocations--;
+ /* Check they actually belong to the same virtual memory block */
+ NTSTATUS Status;
+ MEMORY_BASIC_INFORMATION MemoryBasicInfo;
+
+ Status = ZwQueryVirtualMemory(
+ ZwCurrentProcess(),
+ NextNode->pVirtualBlock,
+ MemoryBasicInformation,
+ &MemoryBasicInfo,
+ sizeof(MemoryBasicInfo),
+ NULL);
+
+ /* There is no way this can fail, we committed this memory! */
+ ASSERT(NT_SUCCESS(Status));
+
+ if ((PUCHAR)MemoryBasicInfo.AllocationBase <= Node->pVirtualBlock)
+ {
+ /* They are adjacent - merge! */
+ Node->nVirtualBlockSize += NextNode->nVirtualBlockSize;
+
+ /* Remove next entry from the list and put it into unused entries list */
+ RemoveEntryList(&NextNode->AvailableEntry);
+ RtlpDphReturnNodeToUnusedList(DphRoot, NextNode);
+ DphRoot->nAvailableAllocations--;
+ }
}
}
}