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)
9 /* INCLUDES *******************************************************************/
17 /* PUBLIC SERVER APIS *********************************************************/
19 CSR_API(BaseSrvDebugProcess
)
21 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
22 return STATUS_NOT_IMPLEMENTED
;
25 CSR_API(BaseSrvRegisterThread
)
27 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
28 return STATUS_NOT_IMPLEMENTED
;
30 CSR_API(BaseSrvSxsCreateActivationContext
)
32 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
33 return STATUS_NOT_IMPLEMENTED
;
36 CSR_API(BaseSrvSetTermsrvAppInstallMode
)
38 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
39 return STATUS_NOT_IMPLEMENTED
;
42 CSR_API(BaseSrvSetTermsrvClientTimeZone
)
44 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
45 return STATUS_NOT_IMPLEMENTED
;
48 CSR_API(BaseSrvUnknown
)
50 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
51 return STATUS_NOT_IMPLEMENTED
;
54 CSR_API(BaseSrvGetTempFile
)
56 static UINT BaseGetTempFileUnique
= 0;
57 PBASE_GET_TEMP_FILE GetTempFile
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.GetTempFileRequest
;
59 /* Return 16-bits ID */
60 GetTempFile
->UniqueID
= (++BaseGetTempFileUnique
& 0xFFFF);
62 DPRINT("Returning: %u\n", GetTempFile
->UniqueID
);
64 return STATUS_SUCCESS
;
67 CSR_API(BaseSrvCreateProcess
)
70 PBASE_CREATE_PROCESS CreateProcessRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.CreateProcessRequest
;
71 HANDLE ProcessHandle
, ThreadHandle
;
72 PCSR_THREAD CsrThread
;
74 ULONG Flags
= 0, VdmPower
= 0, DebugFlags
= 0;
76 /* Get the current client thread */
77 CsrThread
= CsrGetClientThread();
78 ASSERT(CsrThread
!= NULL
);
80 Process
= CsrThread
->Process
;
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);
86 /* Duplicate the process handle */
87 Status
= NtDuplicateObject(Process
->ProcessHandle
,
88 CreateProcessRequest
->ProcessHandle
,
93 DUPLICATE_SAME_ACCESS
);
94 if (!NT_SUCCESS(Status
))
96 DPRINT1("Failed to duplicate process handle: %lx\n", Status
);
100 /* Duplicate the thread handle */
101 Status
= NtDuplicateObject(Process
->ProcessHandle
,
102 CreateProcessRequest
->ThreadHandle
,
107 DUPLICATE_SAME_ACCESS
);
108 if (!NT_SUCCESS(Status
))
110 DPRINT1("Failed to duplicate thread handle: %lx\n", Status
);
111 NtClose(ProcessHandle
);
115 /* See if this is a VDM process */
118 /* Request VDM powers */
119 Status
= NtSetInformationProcess(ProcessHandle
,
120 ProcessWx86Information
,
123 if (!NT_SUCCESS(Status
))
125 DPRINT1("Failed to get VDM powers\n");
126 NtClose(ProcessHandle
);
127 NtClose(ThreadHandle
);
132 /* Flags conversion. FIXME: More need conversion */
133 if (CreateProcessRequest
->CreationFlags
& CREATE_NEW_PROCESS_GROUP
)
135 DebugFlags
|= CsrProcessCreateNewGroup
;
137 if ((Flags
& 2) == 0)
139 /* We are launching a console process */
140 DebugFlags
|= CsrProcessIsConsoleApp
;
143 /* FIXME: SxS Stuff */
145 /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
146 Status
= CsrCreateProcess(ProcessHandle
,
148 &CreateProcessRequest
->ClientId
,
152 if (Status
== STATUS_THREAD_IS_TERMINATING
)
154 DPRINT1("Thread already dead\n");
156 /* Set the special reply value so we don't reply this message back */
157 *ReplyCode
= CsrReplyDeadClient
;
162 /* Check for other failures */
163 if (!NT_SUCCESS(Status
))
165 DPRINT1("Failed to create process/thread structures: %lx\n", Status
);
169 /* FIXME: Should notify user32 */
171 /* Check if this is a VDM process */
172 if (CreateProcessRequest
->VdmBinaryType
)
174 PVDM_CONSOLE_RECORD ConsoleRecord
;
176 if (CreateProcessRequest
->VdmTask
!= 0)
178 /* Get the console record using the task ID */
179 Status
= GetConsoleRecordBySessionId(CreateProcessRequest
->VdmTask
,
184 /* Get the console record using the console handle */
185 Status
= BaseSrvGetConsoleRecord(CreateProcessRequest
->hVDM
,
189 /* Check if it failed */
190 if (!NT_SUCCESS(Status
)) return Status
;
192 /* Store the process ID of the VDM in the console record */
193 ConsoleRecord
->ProcessId
= HandleToUlong(CreateProcessRequest
->ClientId
.UniqueProcess
);
196 /* Return the result of this operation */
200 CSR_API(BaseSrvCreateThread
)
203 PBASE_CREATE_THREAD CreateThreadRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.CreateThreadRequest
;
204 PCSR_THREAD CurrentThread
;
206 PCSR_PROCESS CsrProcess
;
208 /* Get the current CSR thread */
209 CurrentThread
= CsrGetClientThread();
212 DPRINT1("Server Thread TID: [%lx.%lx]\n",
213 CreateThreadRequest
->ClientId
.UniqueProcess
,
214 CreateThreadRequest
->ClientId
.UniqueThread
);
215 return STATUS_SUCCESS
; // server-to-server
218 /* Get the CSR Process for this request */
219 CsrProcess
= CurrentThread
->Process
;
220 if (CsrProcess
->ClientId
.UniqueProcess
!=
221 CreateThreadRequest
->ClientId
.UniqueProcess
)
223 /* This is a remote thread request -- is it within the server itself? */
224 if (CreateThreadRequest
->ClientId
.UniqueProcess
== NtCurrentTeb()->ClientId
.UniqueProcess
)
226 /* Accept this without any further work */
227 return STATUS_SUCCESS
;
230 /* Get the real CSR Process for the remote thread's process */
231 Status
= CsrLockProcessByClientId(CreateThreadRequest
->ClientId
.UniqueProcess
,
233 if (!NT_SUCCESS(Status
)) return Status
;
236 /* Duplicate the thread handle so we can own it */
237 Status
= NtDuplicateObject(CurrentThread
->Process
->ProcessHandle
,
238 CreateThreadRequest
->ThreadHandle
,
243 DUPLICATE_SAME_ACCESS
);
244 if (NT_SUCCESS(Status
))
246 /* Call CSRSRV to tell it about the new thread */
247 Status
= CsrCreateThread(CsrProcess
,
249 &CreateThreadRequest
->ClientId
,
253 /* Unlock the process and return */
254 if (CsrProcess
!= CurrentThread
->Process
) CsrUnlockProcess(CsrProcess
);
258 CSR_API(BaseSrvExitProcess
)
260 PCSR_THREAD CsrThread
= CsrGetClientThread();
261 ASSERT(CsrThread
!= NULL
);
263 /* Set the special reply value so we don't reply this message back */
264 *ReplyCode
= CsrReplyDeadClient
;
266 /* Remove the CSR_THREADs and CSR_PROCESS */
267 return CsrDestroyProcess(&CsrThread
->ClientId
,
268 (NTSTATUS
)((PBASE_API_MESSAGE
)ApiMessage
)->Data
.ExitProcessRequest
.uExitCode
);
271 CSR_API(BaseSrvGetProcessShutdownParam
)
273 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.ShutdownParametersRequest
;
274 PCSR_THREAD CsrThread
= CsrGetClientThread();
277 ShutdownParametersRequest
->ShutdownLevel
= CsrThread
->Process
->ShutdownLevel
;
278 ShutdownParametersRequest
->ShutdownFlags
= CsrThread
->Process
->ShutdownFlags
;
280 return STATUS_SUCCESS
;
283 CSR_API(BaseSrvSetProcessShutdownParam
)
285 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.ShutdownParametersRequest
;
286 PCSR_THREAD CsrThread
= CsrGetClientThread();
289 CsrThread
->Process
->ShutdownLevel
= ShutdownParametersRequest
->ShutdownLevel
;
290 CsrThread
->Process
->ShutdownFlags
= ShutdownParametersRequest
->ShutdownFlags
;
292 return STATUS_SUCCESS
;
295 /* PUBLIC API *****************************************************************/
299 BaseSetProcessCreateNotify(IN BASE_PROCESS_CREATE_NOTIFY_ROUTINE ProcessCreateNotifyProc
)
301 DPRINT("BASESRV: %s(%08lx) called\n", __FUNCTION__
, ProcessCreateNotifyProc
);
302 return STATUS_NOT_IMPLEMENTED
;