[NTOS]: Implement MmDeleteTeb, VADs are now deleted/freed on thread exit as well...
authorSir Richard <sir_richard@svn.reactos.org>
Sat, 24 Jul 2010 16:28:51 +0000 (16:28 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Sat, 24 Jul 2010 16:28:51 +0000 (16:28 +0000)
[NTOS]: Sometimes it seems we hit some bad VADs due to bugs? in the AVL tree implementation. I'm going on vacation for a month and can't look at this, so I've hacked the code to ignore such VADs for now, in the interest of fixing the winetest regression.

svn path=/trunk/; revision=48235

reactos/ntoskrnl/mm/ARM3/miarm.h
reactos/ntoskrnl/mm/ARM3/procsup.c

index 0b4cb68..c577633 100644 (file)
@@ -1121,4 +1121,16 @@ MiRemoveNode(
     IN PMM_AVL_TABLE Table
 );
 
+PMMADDRESS_NODE
+NTAPI
+MiGetPreviousNode(
+    IN PMMADDRESS_NODE Node
+);
+
+PMMADDRESS_NODE
+NTAPI
+MiGetNextNode(
+    IN PMMADDRESS_NODE Node
+);
+
 /* EOF */
index e10fe3c..857a181 100644 (file)
@@ -149,8 +149,57 @@ NTAPI
 MmDeleteTeb(IN PEPROCESS Process,
             IN PTEB Teb)
 {
-    /* Oops J */
-    DPRINT("Leaking 4KB at thread exit, this will be fixed later\n");
+    ULONG_PTR TebEnd;
+    PETHREAD Thread = PsGetCurrentThread();
+    PMMVAD Vad;
+    PMM_AVL_TABLE VadTree = &Process->VadRoot;
+    DPRINT("Deleting TEB: %p in %16s\n", Teb, Process->ImageFileName);
+    
+    /* TEB is one page */
+    TebEnd = (ULONG_PTR)Teb + ROUND_TO_PAGES(sizeof(TEB)) - 1;
+    
+    /* Attach to the process */
+    KeAttachProcess(&Process->Pcb);
+    
+    /* Lock the process address space */
+    KeAcquireGuardedMutex(&Process->AddressCreationLock);
+    
+    /* Find the VAD, make sure it's a TEB VAD */
+    Vad = MiLocateAddress(Teb);
+    DPRINT("Removing node for VAD: %lx %lx\n", Vad->StartingVpn, Vad->EndingVpn);
+    ASSERT(Vad != NULL);    
+    if (Vad->StartingVpn != ((ULONG_PTR)Teb >> PAGE_SHIFT))
+    {
+        /* Bug in the AVL code? */
+        DPRINT1("Corrupted VAD!\n");
+    }
+    else
+    {
+        /* Sanity checks for a valid TEB VAD */
+        ASSERT((Vad->StartingVpn == ((ULONG_PTR)Teb >> PAGE_SHIFT) &&
+               (Vad->EndingVpn == (TebEnd >> PAGE_SHIFT))));
+        ASSERT(Vad->u.VadFlags.NoChange == TRUE);
+        ASSERT(Vad->u2.VadFlags2.MultipleSecured == FALSE);
+
+        /* Lock the working set */
+        MiLockProcessWorkingSet(Process, Thread);
+
+        /* Remove this VAD from the tree */
+        ASSERT(VadTree->NumberGenericTableElements >= 1);
+        MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
+    
+        /* Release the working set */
+        MiUnlockProcessWorkingSet(Process, Thread);
+    
+        /* Remove the VAD */
+        ExFreePool(Vad);
+    }
+
+    /* Release the address space lock */
+    KeReleaseGuardedMutex(&Process->AddressCreationLock);
+    
+    /* Detach */
+    KeDetachProcess();
 }
 
 VOID