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
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;
/* 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;
/* 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);
/* 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);
/* 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);
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;
/* Save the wait IRQL */
WaitIrql = CurrentThread->WaitIrql;
+ /* REACTOS Mm Hack of Doom */
+ MiSyncForContextSwitch(NextThread);
+
/* Swap contexts */
ApcState = KiSwapContext(WaitIrql, CurrentThread);
/* Sanity check */
ASSERT(OldIrql <= DISPATCH_LEVEL);
+ /* REACTOS Mm Hack of Doom */
+ MiSyncForContextSwitch(NextThread);
+
/* Swap to new thread */
KiSwapContext(APC_LEVEL, Thread);
Status = STATUS_SUCCESS;
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
/* 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,