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