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