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