[BASESRV]
[reactos.git] / reactos / 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, DebugFlags = 0, VdmPower = 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 /* Some things should be done if this is a VDM process */
87 if (CreateProcessRequest->VdmBinaryType)
88 {
89 /* We need to set the VDM power later on */
90 VdmPower = 1;
91 }
92
93 /* Duplicate the process handle */
94 Status = NtDuplicateObject(Process->ProcessHandle,
95 CreateProcessRequest->ProcessHandle,
96 NtCurrentProcess(),
97 &ProcessHandle,
98 0,
99 0,
100 DUPLICATE_SAME_ACCESS);
101 if (!NT_SUCCESS(Status))
102 {
103 DPRINT1("Failed to duplicate process handle: %lx\n", Status);
104 return Status;
105 }
106
107 /* Duplicate the thread handle */
108 Status = NtDuplicateObject(Process->ProcessHandle,
109 CreateProcessRequest->ThreadHandle,
110 NtCurrentProcess(),
111 &ThreadHandle,
112 0,
113 0,
114 DUPLICATE_SAME_ACCESS);
115 if (!NT_SUCCESS(Status))
116 {
117 DPRINT1("Failed to duplicate thread handle: %lx\n", Status);
118 NtClose(ProcessHandle);
119 return Status;
120 }
121
122 /* If this is a VDM process, request VDM power */
123 if (VdmPower)
124 {
125 Status = NtSetInformationProcess(ProcessHandle,
126 ProcessWx86Information,
127 &VdmPower,
128 sizeof(VdmPower));
129 if (!NT_SUCCESS(Status))
130 {
131 DPRINT1("Failed to get VDM powers\n");
132 NtClose(ProcessHandle);
133 NtClose(ThreadHandle);
134 return Status;
135 }
136 }
137
138 /* Flags conversion. FIXME: More need conversion */
139 if (CreateProcessRequest->CreationFlags & CREATE_NEW_PROCESS_GROUP)
140 {
141 DebugFlags |= CsrProcessCreateNewGroup;
142 }
143 if ((Flags & 2) == 0)
144 {
145 /* We are launching a console process */
146 DebugFlags |= CsrProcessIsConsoleApp;
147 }
148
149 /* FIXME: SxS Stuff */
150
151 /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
152 Status = CsrCreateProcess(ProcessHandle,
153 ThreadHandle,
154 &CreateProcessRequest->ClientId,
155 Process->NtSession,
156 DebugFlags,
157 NULL);
158 if (Status == STATUS_THREAD_IS_TERMINATING)
159 {
160 DPRINT1("Thread already dead\n");
161
162 /* Set the special reply value so we don't reply this message back */
163 *ReplyCode = CsrReplyDeadClient;
164
165 return Status;
166 }
167
168 /* Check for other failures */
169 if (!NT_SUCCESS(Status))
170 {
171 DPRINT1("Failed to create process/thread structures: %lx\n", Status);
172 return Status;
173 }
174
175 /* FIXME: Should notify user32 */
176
177 /* Check if this is a VDM process */
178 if (CreateProcessRequest->VdmBinaryType)
179 {
180 PVDM_CONSOLE_RECORD ConsoleRecord;
181
182 if (CreateProcessRequest->VdmTask != 0)
183 {
184 /* Get the console record using the task ID */
185 Status = GetConsoleRecordBySessionId(CreateProcessRequest->VdmTask,
186 &ConsoleRecord);
187 }
188 else
189 {
190 /* Get the console record using the console handle */
191 Status = BaseSrvGetConsoleRecord(CreateProcessRequest->hVDM,
192 &ConsoleRecord);
193 }
194
195 /* Check if it failed */
196 if (!NT_SUCCESS(Status)) return Status;
197
198 /* Store the process ID of the VDM in the console record */
199 ConsoleRecord->ProcessId = HandleToUlong(CreateProcessRequest->ClientId.UniqueProcess);
200 }
201
202 /* Return the result of this operation */
203 return Status;
204 }
205
206 CSR_API(BaseSrvCreateThread)
207 {
208 NTSTATUS Status;
209 PBASE_CREATE_THREAD CreateThreadRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CreateThreadRequest;
210 PCSR_THREAD CurrentThread;
211 HANDLE ThreadHandle;
212 PCSR_PROCESS CsrProcess;
213
214 /* Get the current CSR thread */
215 CurrentThread = CsrGetClientThread();
216 if (!CurrentThread)
217 {
218 DPRINT1("Server Thread TID: [%lx.%lx]\n",
219 CreateThreadRequest->ClientId.UniqueProcess,
220 CreateThreadRequest->ClientId.UniqueThread);
221 return STATUS_SUCCESS; // server-to-server
222 }
223
224 /* Get the CSR Process for this request */
225 CsrProcess = CurrentThread->Process;
226 if (CsrProcess->ClientId.UniqueProcess !=
227 CreateThreadRequest->ClientId.UniqueProcess)
228 {
229 /* This is a remote thread request -- is it within the server itself? */
230 if (CreateThreadRequest->ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
231 {
232 /* Accept this without any further work */
233 return STATUS_SUCCESS;
234 }
235
236 /* Get the real CSR Process for the remote thread's process */
237 Status = CsrLockProcessByClientId(CreateThreadRequest->ClientId.UniqueProcess,
238 &CsrProcess);
239 if (!NT_SUCCESS(Status)) return Status;
240 }
241
242 /* Duplicate the thread handle so we can own it */
243 Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
244 CreateThreadRequest->ThreadHandle,
245 NtCurrentProcess(),
246 &ThreadHandle,
247 0,
248 0,
249 DUPLICATE_SAME_ACCESS);
250 if (NT_SUCCESS(Status))
251 {
252 /* Call CSRSRV to tell it about the new thread */
253 Status = CsrCreateThread(CsrProcess,
254 ThreadHandle,
255 &CreateThreadRequest->ClientId,
256 TRUE);
257 }
258
259 /* Unlock the process and return */
260 if (CsrProcess != CurrentThread->Process) CsrUnlockProcess(CsrProcess);
261 return Status;
262 }
263
264 CSR_API(BaseSrvExitProcess)
265 {
266 PCSR_THREAD CsrThread = CsrGetClientThread();
267 ASSERT(CsrThread != NULL);
268
269 /* Set the special reply value so we don't reply this message back */
270 *ReplyCode = CsrReplyDeadClient;
271
272 /* Remove the CSR_THREADs and CSR_PROCESS */
273 return CsrDestroyProcess(&CsrThread->ClientId,
274 (NTSTATUS)((PBASE_API_MESSAGE)ApiMessage)->Data.ExitProcessRequest.uExitCode);
275 }
276
277 CSR_API(BaseSrvGetProcessShutdownParam)
278 {
279 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ShutdownParametersRequest;
280 PCSR_THREAD CsrThread = CsrGetClientThread();
281 ASSERT(CsrThread);
282
283 ShutdownParametersRequest->ShutdownLevel = CsrThread->Process->ShutdownLevel;
284 ShutdownParametersRequest->ShutdownFlags = CsrThread->Process->ShutdownFlags;
285
286 return STATUS_SUCCESS;
287 }
288
289 CSR_API(BaseSrvSetProcessShutdownParam)
290 {
291 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ShutdownParametersRequest;
292 PCSR_THREAD CsrThread = CsrGetClientThread();
293 ASSERT(CsrThread);
294
295 CsrThread->Process->ShutdownLevel = ShutdownParametersRequest->ShutdownLevel;
296 CsrThread->Process->ShutdownFlags = ShutdownParametersRequest->ShutdownFlags;
297
298 return STATUS_SUCCESS;
299 }
300
301 /* PUBLIC API *****************************************************************/
302
303 NTSTATUS
304 NTAPI
305 BaseSetProcessCreateNotify(IN BASE_PROCESS_CREATE_NOTIFY_ROUTINE ProcessCreateNotifyProc)
306 {
307 DPRINT("BASESRV: %s(%08lx) called\n", __FUNCTION__, ProcessCreateNotifyProc);
308 return STATUS_NOT_IMPLEMENTED;
309 }
310
311 /* EOF */