update for HEAD-2003091401
[reactos.git] / ntoskrnl / ke / process.c
index 18acafd..16d03a8 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 KeAttachProcess (PEPROCESS Process)
 {
    KIRQL oldlvl;
    PETHREAD CurrentThread;
+   PULONG AttachedProcessPageDir;
    ULONG PageDir;
    
    DPRINT("KeAttachProcess(Process %x)\n",Process);
@@ -53,23 +57,39 @@ KeAttachProcess (PEPROCESS Process)
    if (CurrentThread->OldProcess != NULL)
      {
        DbgPrint("Invalid attach (thread is already attached)\n");
-       KeBugCheck(0);
+       KEBUGCHECK(0);
      }
    
    KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
-   
+
+   /* The stack of the current process may be located in a page which is
+      not present in the page directory of the process we're attaching to.
+      That would lead to a page fault when this function returns. However,
+      since the processor can't call the page fault handler 'cause it can't
+      push EIP on the stack, this will show up as a stack fault which will
+      crash the entire system.
+      To prevent this, make sure the page directory of the process we're
+      attaching to is up-to-date. */
+
+   AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase);
+   MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb);
+   ExUnmapPage(AttachedProcessPageDir);
+
    CurrentThread->OldProcess = PsGetCurrentProcess();
    CurrentThread->ThreadsProcess = Process;
-   PageDir = CurrentThread->ThreadsProcess->Pcb.DirectoryTableBase.u.LowPart;
+   PageDir = Process->Pcb.DirectoryTableBase.u.LowPart;
    DPRINT("Switching process context to %x\n",PageDir)
    __asm__("movl %0,%%cr3\n\t"
-          : /* no inputs */
+          : /* no outputs */
           : "r" (PageDir));
    
    
    KeLowerIrql(oldlvl);
 }
 
+/*
+ * @implemented
+ */
 VOID STDCALL
 KeDetachProcess (VOID)
 {
@@ -84,7 +104,7 @@ KeDetachProcess (VOID)
    if (CurrentThread->OldProcess == NULL)
      {
        DbgPrint("Invalid detach (thread was not attached)\n");
-       KeBugCheck(0);
+       KEBUGCHECK(0);
      }
    
    KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);