Check for overlapping memory views and delete the offending view if
necessary, to ensure we never have two views covering the same
address.

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 3245854..84dbe56 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -238,6 +238,27 @@
 
 
 /***********************************************************************
+ *           VIRTUAL_DeleteView
+ * Deletes a view.
+ *
+ * RETURNS
+ *	None
+ */
+static void VIRTUAL_DeleteView( FILE_VIEW *view ) /* [in] View */
+{
+    RtlEnterCriticalSection(&csVirtual);
+    if (!(view->flags & VFLAG_SYSTEM))
+        munmap( (void *)view->base, view->size );
+    if (view->next) view->next->prev = view->prev;
+    if (view->prev) view->prev->next = view->next;
+    else VIRTUAL_FirstView = view->next;
+    RtlLeaveCriticalSection(&csVirtual);
+    if (view->mapping) NtClose( view->mapping );
+    free( view );
+}
+
+
+/***********************************************************************
  *           VIRTUAL_CreateView
  *
  * Create a new view and add it in the linked list.
@@ -290,6 +311,27 @@
         view->prev = prev;
         if (view->next) view->next->prev = view;
         prev->next  = view;
+
+        /* Check for overlapping views. This can happen if the previous view
+         * was a system view that got unmapped behind our back. In that case
+         * we recover by simply deleting it. */
+        if ((char *)prev->base + prev->size > (char *)base)
+        {
+            TRACE( "overlapping prev view %p-%p for %p-%p\n",
+                   prev->base, (char *)prev->base + prev->size,
+                   base, (char *)base + view->size );
+            assert( view->prev->flags & VFLAG_SYSTEM );
+            VIRTUAL_DeleteView( view->prev );
+        }
+    }
+    /* check for overlap with next too */
+    if (view->next && (char *)base + view->size > (char *)view->next->base)
+    {
+        TRACE( "overlapping next view %p-%p for %p-%p\n",
+               view->next->base, (char *)view->next->base + view->next->size,
+               base, (char *)base + view->size );
+        assert( view->next->flags & VFLAG_SYSTEM );
+        VIRTUAL_DeleteView( view->next );
     }
     RtlLeaveCriticalSection(&csVirtual);
     VIRTUAL_DEBUG_DUMP_VIEW( view );
@@ -298,27 +340,6 @@
 
 
 /***********************************************************************
- *           VIRTUAL_DeleteView
- * Deletes a view.
- *
- * RETURNS
- *	None
- */
-static void VIRTUAL_DeleteView( FILE_VIEW *view ) /* [in] View */
-{
-    if (!(view->flags & VFLAG_SYSTEM))
-        munmap( (void *)view->base, view->size );
-    RtlEnterCriticalSection(&csVirtual);
-    if (view->next) view->next->prev = view->prev;
-    if (view->prev) view->prev->next = view->next;
-    else VIRTUAL_FirstView = view->next;
-    RtlLeaveCriticalSection(&csVirtual);
-    if (view->mapping) NtClose( view->mapping );
-    free( view );
-}
-
-
-/***********************************************************************
  *           VIRTUAL_GetUnixProt
  *
  * Convert page protections to protection for mmap/mprotect.