Laa-a-a-a-dies and gentlemen.....
authorAlex Ionescu <aionescu@gmail.com>
Thu, 26 Jan 2012 21:16:59 +0000 (21:16 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Thu, 26 Jan 2012 21:16:59 +0000 (21:16 +0000)
For your unique, viewing and executing pleasure..
For one time only....by popular demand....
The one...
The only...
The unforgettable, unforgivable...
Meanest, baddest, piece of code around...
He's back..... with a vengeance...
The ultimate...
Mega...
Uber..
Amazing...
HACK
OF
DOOOOOOOOOOOOOOOOOOOOOOOOOOOOOM
</applause>

svn path=/trunk/; revision=55227

reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/ke/i386/thrdini.c
reactos/ntoskrnl/ke/procobj.c
reactos/ntoskrnl/ke/thrdobj.c
reactos/ntoskrnl/ke/thrdschd.c
reactos/ntoskrnl/mm/i386/page.c
reactos/ntoskrnl/mm/mmfault.c

index 09918a6..278b667 100644 (file)
@@ -6,6 +6,20 @@
 
 struct _EPROCESS;
 
+/* ReactOS Mm Hacks */
+VOID
+FASTCALL
+MiSyncForProcessAttach(
+    IN PKTHREAD NextThread,
+    IN PEPROCESS Process
+);
+
+VOID
+FASTCALL
+MiSyncForContextSwitch(
+    IN PKTHREAD Thread
+);
+
 extern PMMSUPPORT MmKernelAddressSpace;
 extern PFN_COUNT MiFreeSwapPages;
 extern PFN_COUNT MiUsedSwapPages;
index 8ee6314..cb120d3 100644 (file)
@@ -433,6 +433,9 @@ KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame,
     /* Get thread pointers */
     OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
     NewThread = Pcr->PrcbData.CurrentThread;
+    
+    /* ReactOS Mm Hack */
+    MiSyncForContextSwitch(NewThread);
 
     /* Get the old thread and set its kernel stack */
     OldThread->KernelStack = SwitchFrame;
index 7051c82..c8de4f0 100644 (file)
@@ -97,6 +97,9 @@ KiAttachProcess(IN PKTHREAD Thread,
         /* Release lock */
         KiReleaseApcLockFromDpcLevel(ApcLock);
 
+        /* Make sure that we are in the right page directory (ReactOS Mm Hack) */
+        MiSyncForProcessAttach(Thread, (PEPROCESS)Process);
+        
         /* Swap Processes */
         KiSwapProcess(Process, SavedApcState->Process);
 
@@ -615,6 +618,9 @@ KeDetachProcess(VOID)
     /* Release lock */
     KiReleaseApcLockFromDpcLevel(&ApcLock);
 
+    /* Make sure that we are in the right page directory (ReactOS Mm Hack) */
+    MiSyncForProcessAttach(Thread, (PEPROCESS)Process);
+
     /* Swap Processes */
     KiSwapProcess(Thread->ApcState.Process, Process);
 
@@ -782,6 +788,9 @@ KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
     /* Release lock */
     KiReleaseApcLockFromDpcLevel(&ApcLock);
 
+    /* Make sure that we are in the right page directory (ReactOS Mm Hack) */
+    MiSyncForProcessAttach(Thread, (PEPROCESS)Process);
+
     /* Swap Processes */
     KiSwapProcess(Thread->ApcState.Process, Process);
 
index cfccf0d..686fbbb 100644 (file)
@@ -856,6 +856,9 @@ KeInitThread(IN OUT PKTHREAD Thread,
     Thread->StackBase = KernelStack;
     Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
     Thread->KernelStackResident = TRUE;
+    
+    /* Make sure that we are in the right page directory (ReactOS Mm Hack) */
+    MiSyncForProcessAttach(Thread, (PEPROCESS)Process);
 
     /* Enter SEH to avoid crashes due to user mode */
     Status = STATUS_SUCCESS;
index ee418c7..b9a0638 100644 (file)
@@ -394,6 +394,9 @@ KiSwapThread(IN PKTHREAD CurrentThread,
     /* Save the wait IRQL */
     WaitIrql = CurrentThread->WaitIrql;
 
+    /* REACTOS Mm Hack of Doom */
+    MiSyncForContextSwitch(NextThread);
+    
     /* Swap contexts */
     ApcState = KiSwapContext(WaitIrql, CurrentThread);
 
@@ -790,6 +793,9 @@ NtYieldExecution(VOID)
             /* Sanity check */
             ASSERT(OldIrql <= DISPATCH_LEVEL);
 
+            /* REACTOS Mm Hack of Doom */
+            MiSyncForContextSwitch(NextThread);
+            
             /* Swap to new thread */
             KiSwapContext(APC_LEVEL, Thread);
             Status = STATUS_SUCCESS;
index 9ebf1bd..2b80afd 100644 (file)
@@ -1028,6 +1028,54 @@ MmGetPhysicalAddress(PVOID vaddr)
     return p;
 }
 
+VOID
+NTAPI
+MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
+{
+    ULONG StartOffset, EndOffset, Offset;
+    PULONG Pde;
+    
+    //
+    // Check if the process isn't there anymore
+    // This is probably a bad sign, since it means the caller is setting cr3 to
+    // 0 or something...
+    //
+    if ((PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]) == 0) && (Process != PsGetCurrentProcess()))
+    {
+        DPRINT1("Process: %16s is dead: %p\n", Process->ImageFileName, Process->Pcb.DirectoryTableBase[0]);
+        ASSERT(FALSE);
+        return;
+    }
+
+    if (Address < MmSystemRangeStart)
+    {
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+
+    StartOffset = ADDR_TO_PDE_OFFSET(Address);
+    EndOffset = ADDR_TO_PDE_OFFSET((PVOID)((ULONG_PTR)Address + Size));
+
+    if (Process != NULL && Process != PsGetCurrentProcess())
+    {
+        Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
+    }
+    else
+    {
+        Pde = (PULONG)PAGEDIRECTORY_MAP;
+    }
+    for (Offset = StartOffset; Offset <= EndOffset; Offset++)
+    {
+        if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP))
+        {
+            InterlockedCompareExchangePte(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0);
+        }
+    }
+    if (Pde != (PULONG)PAGEDIRECTORY_MAP)
+    {
+        MmDeleteHyperspaceMapping(Pde);
+    }
+}
+
 VOID
 INIT_FUNCTION
 NTAPI
index b8628a8..c749f18 100644 (file)
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
+VOID
+FASTCALL
+MiSyncForProcessAttach(IN PKTHREAD Thread,
+                       IN PEPROCESS Process)
+{
+    PETHREAD Ethread = CONTAINING_RECORD(Thread, ETHREAD, Tcb);
+    //DPRINT1("Hack sync for process: %p and thread: %p\n", Process, Thread);
+    //DPRINT1("Thread stack hack: %p %d\n", Thread->StackLimit, Thread->LargeStack);
+
+    /* Hack Sync because Mm is broken */
+    MmUpdatePageDir(Process, Ethread, sizeof(ETHREAD));
+    MmUpdatePageDir(Process, Ethread->ThreadsProcess, sizeof(EPROCESS));
+    MmUpdatePageDir(Process,
+                    (PVOID)Thread->StackLimit,
+                    Thread->LargeStack ?
+                    KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE);
+}
+
+VOID
+FASTCALL
+MiSyncForContextSwitch(IN PKTHREAD Thread)
+{
+    PVOID Process = PsGetCurrentProcess();
+    PETHREAD Ethread = CONTAINING_RECORD(Thread, ETHREAD, Tcb);
+    //DPRINT1("Hack sync for thread: %p and process: %p\n", Thread, Process);
+    //DPRINT1("Thread stack hack: %p %d\n", Thread->StackLimit, Thread->LargeStack);
+    
+    /* Hack Sync because Mm is broken */
+    MmUpdatePageDir(Process, Ethread->ThreadsProcess, sizeof(EPROCESS));
+    MmUpdatePageDir(Process,
+                    (PVOID)Thread->StackLimit,
+                    Thread->LargeStack ?
+                    KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE);
+}
+
 NTSTATUS
 NTAPI
 MmpAccessFault(KPROCESSOR_MODE Mode,