Continue of MSVC-compiling changes....
[reactos.git] / reactos / ntoskrnl / ke / process.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: process.c,v 1.18 2003/12/30 18:52:04 fireball Exp $
20 *
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/process.c
23 * PURPOSE: Microkernel process management
24 * PROGRAMMER: David Welch (welch@cwcom.net)
25 * PORTABILITY: No.
26 * UPDATE HISTORY:
27 * Created 22/05/98
28 */
29
30 /* INCLUDES *****************************************************************/
31
32 #include <ddk/ntddk.h>
33 #include <internal/ke.h>
34 #include <internal/mm.h>
35 #include <internal/ps.h>
36
37 #define NDEBUG
38 #include <internal/debug.h>
39
40 /* FUNCTIONS *****************************************************************/
41
42 /*
43 * @implemented
44 */
45 VOID STDCALL
46 KeAttachProcess (PEPROCESS Process)
47 {
48 KIRQL oldlvl;
49 PETHREAD CurrentThread;
50 PULONG AttachedProcessPageDir;
51 ULONG PageDir;
52
53 DPRINT("KeAttachProcess(Process %x)\n",Process);
54
55 CurrentThread = PsGetCurrentThread();
56
57 if (CurrentThread->OldProcess != NULL)
58 {
59 DbgPrint("Invalid attach (thread is already attached)\n");
60 KEBUGCHECK(0);
61 }
62
63 KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
64
65 KiSwapApcEnvironment(&CurrentThread->Tcb, &Process->Pcb);
66
67 /* The stack of the current process may be located in a page which is
68 not present in the page directory of the process we're attaching to.
69 That would lead to a page fault when this function returns. However,
70 since the processor can't call the page fault handler 'cause it can't
71 push EIP on the stack, this will show up as a stack fault which will
72 crash the entire system.
73 To prevent this, make sure the page directory of the process we're
74 attaching to is up-to-date. */
75
76 AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase);
77 MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb);
78 ExUnmapPage(AttachedProcessPageDir);
79
80 CurrentThread->OldProcess = PsGetCurrentProcess();
81 CurrentThread->ThreadsProcess = Process;
82 PageDir = Process->Pcb.DirectoryTableBase.u.LowPart;
83 DPRINT("Switching process context to %x\n",PageDir);
84 #if defined(__GNUC__)
85 __asm__("movl %0,%%cr3\n\t"
86 : /* no outputs */
87 : "r" (PageDir));
88 #elif defined(_MSC_VER)
89 __asm mov eax, PageDir;
90 __asm mov cr3, eax;
91 #else
92 #error Unknown compiler for inline assembler
93 #endif
94 KeLowerIrql(oldlvl);
95 }
96
97 /*
98 * @implemented
99 */
100 VOID STDCALL
101 KeDetachProcess (VOID)
102 {
103 KIRQL oldlvl;
104 PETHREAD CurrentThread;
105 ULONG PageDir;
106
107 DPRINT("KeDetachProcess()\n");
108
109 CurrentThread = PsGetCurrentThread();
110
111 if (CurrentThread->OldProcess == NULL)
112 {
113 DbgPrint("Invalid detach (thread was not attached)\n");
114 KEBUGCHECK(0);
115 }
116
117 KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
118
119 KiSwapApcEnvironment(&CurrentThread->Tcb, &CurrentThread->OldProcess->Pcb);
120
121 CurrentThread->ThreadsProcess = CurrentThread->OldProcess;
122 CurrentThread->OldProcess = NULL;
123 PageDir = CurrentThread->ThreadsProcess->Pcb.DirectoryTableBase.u.LowPart;
124 #if defined(__GNUC__)
125 __asm__("movl %0,%%cr3\n\t"
126 : /* no inputs */
127 : "r" (PageDir));
128 #elif defined(_MSC_VER)
129 __asm mov eax, PageDir;
130 __asm mov cr3, eax;
131 #else
132 #error Unknown compiler for inline assembler
133 #endif
134
135 KeLowerIrql(oldlvl);
136 }
137
138 /* EOF */