[NTVDM][KERNEL32]
[reactos.git] / subsystems / win / basesrv / proc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Base API Server DLL
4 * FILE: subsystems/win/basesrv/proc.c
5 * PURPOSE: Process and Thread Management
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "basesrv.h"
12 #include "vdm.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* PUBLIC SERVER APIS *********************************************************/
18
19 CSR_API(BaseSrvDebugProcess)
20 {
21 DPRINT1("%s not yet implemented\n", __FUNCTION__);
22 return STATUS_NOT_IMPLEMENTED;
23 }
24
25 CSR_API(BaseSrvRegisterThread)
26 {
27 DPRINT1("%s not yet implemented\n", __FUNCTION__);
28 return STATUS_NOT_IMPLEMENTED;
29 }
30 CSR_API(BaseSrvSxsCreateActivationContext)
31 {
32 DPRINT1("%s not yet implemented\n", __FUNCTION__);
33 return STATUS_NOT_IMPLEMENTED;
34 }
35
36 CSR_API(BaseSrvSetTermsrvAppInstallMode)
37 {
38 DPRINT1("%s not yet implemented\n", __FUNCTION__);
39 return STATUS_NOT_IMPLEMENTED;
40 }
41
42 CSR_API(BaseSrvSetTermsrvClientTimeZone)
43 {
44 DPRINT1("%s not yet implemented\n", __FUNCTION__);
45 return STATUS_NOT_IMPLEMENTED;
46 }
47
48 CSR_API(BaseSrvUnknown)
49 {
50 DPRINT1("%s not yet implemented\n", __FUNCTION__);
51 return STATUS_NOT_IMPLEMENTED;
52 }
53
54 CSR_API(BaseSrvGetTempFile)
55 {
56 static UINT BaseGetTempFileUnique = 0;
57 PBASE_GET_TEMP_FILE GetTempFile = &((PBASE_API_MESSAGE)ApiMessage)->Data.GetTempFileRequest;
58
59 /* Return 16-bits ID */
60 GetTempFile->UniqueID = (++BaseGetTempFileUnique & 0xFFFF);
61
62 DPRINT("Returning: %u\n", GetTempFile->UniqueID);
63
64 return STATUS_SUCCESS;
65 }
66
67 CSR_API(BaseSrvCreateProcess)
68 {
69 NTSTATUS Status;
70 PBASE_CREATE_PROCESS CreateProcessRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CreateProcessRequest;
71 HANDLE ProcessHandle, ThreadHandle;
72 PCSR_THREAD CsrThread;
73 PCSR_PROCESS Process;
74 ULONG Flags = 0, VdmPower = 0, DebugFlags = 0;
75
76 /* Get the current client thread */
77 CsrThread = CsrGetClientThread();
78 ASSERT(CsrThread != NULL);
79
80 Process = CsrThread->Process;
81
82 /* Extract the flags out of the process handle */
83 Flags = (ULONG_PTR)CreateProcessRequest->ProcessHandle & 3;
84 CreateProcessRequest->ProcessHandle = (HANDLE)((ULONG_PTR)CreateProcessRequest->ProcessHandle & ~3);
85
86 /* Duplicate the process handle */
87 Status = NtDuplicateObject(Process->ProcessHandle,
88 CreateProcessRequest->ProcessHandle,
89 NtCurrentProcess(),
90 &ProcessHandle,
91 0,
92 0,
93 DUPLICATE_SAME_ACCESS);
94 if (!NT_SUCCESS(Status))
95 {
96 DPRINT1("Failed to duplicate process handle: %lx\n", Status);
97 return Status;
98 }
99
100 /* Duplicate the thread handle */
101 Status = NtDuplicateObject(Process->ProcessHandle,
102 CreateProcessRequest->ThreadHandle,
103 NtCurrentProcess(),
104 &ThreadHandle,
105 0,
106 0,
107 DUPLICATE_SAME_ACCESS);
108 if (!NT_SUCCESS(Status))
109 {
110 DPRINT1("Failed to duplicate thread handle: %lx\n", Status);
111 NtClose(ProcessHandle);
112 return Status;
113 }
114
115 /* See if this is a VDM process */
116 if (VdmPower)
117 {
118 /* Request VDM powers */
119 Status = NtSetInformationProcess(ProcessHandle,
120 ProcessWx86Information,
121 &VdmPower,
122 sizeof(VdmPower));
123 if (!NT_SUCCESS(Status))
124 {
125 DPRINT1("Failed to get VDM powers\n");
126 NtClose(ProcessHandle);
127 NtClose(ThreadHandle);
128 return Status;
129 }
130 }
131
132 /* Flags conversion. FIXME: More need conversion */
133 if (CreateProcessRequest->CreationFlags & CREATE_NEW_PROCESS_GROUP)
134 {
135 DebugFlags |= CsrProcessCreateNewGroup;
136 }
137 if ((Flags & 2) == 0)
138 {
139 /* We are launching a console process */
140 DebugFlags |= CsrProcessIsConsoleApp;
141 }
142
143 /* FIXME: SxS Stuff */
144
145 /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
146 Status = CsrCreateProcess(ProcessHandle,
147 ThreadHandle,
148 &CreateProcessRequest->ClientId,
149 Process->NtSession,
150 DebugFlags,
151 NULL);
152 if (Status == STATUS_THREAD_IS_TERMINATING)
153 {
154 DPRINT1("Thread already dead\n");
155
156 /* Set the special reply value so we don't reply this message back */
157 *ReplyCode = CsrReplyDeadClient;
158
159 return Status;
160 }
161
162 /* Check for other failures */
163 if (!NT_SUCCESS(Status))
164 {
165 DPRINT1("Failed to create process/thread structures: %lx\n", Status);
166 return Status;
167 }
168
169 /* FIXME: Should notify user32 */
170
171 /* Check if this is a VDM process */
172 if (CreateProcessRequest->VdmBinaryType)
173 {
174 PVDM_CONSOLE_RECORD ConsoleRecord;
175
176 if (CreateProcessRequest->VdmTask != 0)
177 {
178 /* Get the console record using the task ID */
179 Status = GetConsoleRecordBySessionId(CreateProcessRequest->VdmTask,
180 &ConsoleRecord);
181 }
182 else
183 {
184 /* Get the console record using the console handle */
185 Status = BaseSrvGetConsoleRecord(CreateProcessRequest->hVDM,
186 &ConsoleRecord);
187 }
188
189 /* Check if it failed */
190 if (!NT_SUCCESS(Status)) return Status;
191
192 /* Store the process ID of the VDM in the console record */
193 ConsoleRecord->ProcessId = HandleToUlong(CreateProcessRequest->ClientId.UniqueProcess);
194 }
195
196 /* Return the result of this operation */
197 return Status;
198 }
199
200 CSR_API(BaseSrvCreateThread)
201 {
202 NTSTATUS Status;
203 PBASE_CREATE_THREAD CreateThreadRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CreateThreadRequest;
204 PCSR_THREAD CurrentThread;
205 HANDLE ThreadHandle;
206 PCSR_PROCESS CsrProcess;
207
208 /* Get the current CSR thread */
209 CurrentThread = CsrGetClientThread();
210 if (!CurrentThread)
211 {
212 DPRINT1("Server Thread TID: [%lx.%lx]\n",
213 CreateThreadRequest->ClientId.UniqueProcess,
214 CreateThreadRequest->ClientId.UniqueThread);
215 return STATUS_SUCCESS; // server-to-server
216 }
217
218 /* Get the CSR Process for this request */
219 CsrProcess = CurrentThread->Process;
220 if (CsrProcess->ClientId.UniqueProcess !=
221 CreateThreadRequest->ClientId.UniqueProcess)
222 {
223 /* This is a remote thread request -- is it within the server itself? */
224 if (CreateThreadRequest->ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
225 {
226 /* Accept this without any further work */
227 return STATUS_SUCCESS;
228 }
229
230 /* Get the real CSR Process for the remote thread's process */
231 Status = CsrLockProcessByClientId(CreateThreadRequest->ClientId.UniqueProcess,
232 &CsrProcess);
233 if (!NT_SUCCESS(Status)) return Status;
234 }
235
236 /* Duplicate the thread handle so we can own it */
237 Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
238 CreateThreadRequest->ThreadHandle,
239 NtCurrentProcess(),
240 &ThreadHandle,
241 0,
242 0,
243 DUPLICATE_SAME_ACCESS);
244 if (NT_SUCCESS(Status))
245 {
246 /* Call CSRSRV to tell it about the new thread */
247 Status = CsrCreateThread(CsrProcess,
248 ThreadHandle,
249 &CreateThreadRequest->ClientId,
250 TRUE);
251 }
252
253 /* Unlock the process and return */
254 if (CsrProcess != CurrentThread->Process) CsrUnlockProcess(CsrProcess);
255 return Status;
256 }
257
258 CSR_API(BaseSrvExitProcess)
259 {
260 PCSR_THREAD CsrThread = CsrGetClientThread();
261 ASSERT(CsrThread != NULL);
262
263 /* Set the special reply value so we don't reply this message back */
264 *ReplyCode = CsrReplyDeadClient;
265
266 /* Remove the CSR_THREADs and CSR_PROCESS */
267 return CsrDestroyProcess(&CsrThread->ClientId,
268 (NTSTATUS)((PBASE_API_MESSAGE)ApiMessage)->Data.ExitProcessRequest.uExitCode);
269 }
270
271 CSR_API(BaseSrvGetProcessShutdownParam)
272 {
273 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ShutdownParametersRequest;
274 PCSR_THREAD CsrThread = CsrGetClientThread();
275 ASSERT(CsrThread);
276
277 ShutdownParametersRequest->ShutdownLevel = CsrThread->Process->ShutdownLevel;
278 ShutdownParametersRequest->ShutdownFlags = CsrThread->Process->ShutdownFlags;
279
280 return STATUS_SUCCESS;
281 }
282
283 CSR_API(BaseSrvSetProcessShutdownParam)
284 {
285 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ShutdownParametersRequest;
286 PCSR_THREAD CsrThread = CsrGetClientThread();
287 ASSERT(CsrThread);
288
289 CsrThread->Process->ShutdownLevel = ShutdownParametersRequest->ShutdownLevel;
290 CsrThread->Process->ShutdownFlags = ShutdownParametersRequest->ShutdownFlags;
291
292 return STATUS_SUCCESS;
293 }
294
295 /* PUBLIC API *****************************************************************/
296
297 NTSTATUS
298 NTAPI
299 BaseSetProcessCreateNotify(IN BASE_PROCESS_CREATE_NOTIFY_ROUTINE ProcessCreateNotifyProc)
300 {
301 DPRINT("BASESRV: %s(%08lx) called\n", __FUNCTION__, ProcessCreateNotifyProc);
302 return STATUS_NOT_IMPLEMENTED;
303 }
304
305 /* EOF */