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 /* GLOBALS ********************************************************************/
19 /* User notification procedure to be called when a process is created */
20 static BASE_PROCESS_CREATE_NOTIFY_ROUTINE UserNotifyProcessCreate
= NULL
;
22 /* PUBLIC SERVER APIS *********************************************************/
24 CSR_API(BaseSrvDebugProcess
)
27 return STATUS_UNSUCCESSFUL
;
30 CSR_API(BaseSrvRegisterThread
)
32 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
33 return STATUS_NOT_IMPLEMENTED
;
36 CSR_API(BaseSrvSxsCreateActivationContext
)
38 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
39 return STATUS_NOT_IMPLEMENTED
;
42 CSR_API(BaseSrvSetTermsrvAppInstallMode
)
44 DPRINT1("%s not yet implemented\n", __FUNCTION__
);
45 return STATUS_NOT_IMPLEMENTED
;
48 CSR_API(BaseSrvSetTermsrvClientTimeZone
)
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, DebugFlags
= 0, VdmPower
= 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 /* Some things should be done if this is a VDM process */
87 if (CreateProcessRequest
->VdmBinaryType
)
89 /* We need to set the VDM power later on */
93 /* Duplicate the process handle */
94 Status
= NtDuplicateObject(Process
->ProcessHandle
,
95 CreateProcessRequest
->ProcessHandle
,
100 DUPLICATE_SAME_ACCESS
);
101 if (!NT_SUCCESS(Status
))
103 DPRINT1("Failed to duplicate process handle: %lx\n", Status
);
107 /* Duplicate the thread handle */
108 Status
= NtDuplicateObject(Process
->ProcessHandle
,
109 CreateProcessRequest
->ThreadHandle
,
114 DUPLICATE_SAME_ACCESS
);
115 if (!NT_SUCCESS(Status
))
117 DPRINT1("Failed to duplicate thread handle: %lx\n", Status
);
118 NtClose(ProcessHandle
);
122 /* If this is a VDM process, request VDM power */
125 Status
= NtSetInformationProcess(ProcessHandle
,
126 ProcessWx86Information
,
129 if (!NT_SUCCESS(Status
))
131 DPRINT1("Failed to get VDM powers\n");
132 NtClose(ProcessHandle
);
133 NtClose(ThreadHandle
);
138 /* Flags conversion. FIXME: More need conversion */
139 if (CreateProcessRequest
->CreationFlags
& CREATE_NEW_PROCESS_GROUP
)
141 DebugFlags
|= CsrProcessCreateNewGroup
;
143 if ((Flags
& 2) == 0)
145 /* We are launching a console process */
146 DebugFlags
|= CsrProcessIsConsoleApp
;
149 /* FIXME: SxS Stuff */
151 /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
152 Status
= CsrCreateProcess(ProcessHandle
,
154 &CreateProcessRequest
->ClientId
,
158 if (Status
== STATUS_THREAD_IS_TERMINATING
)
160 DPRINT1("Thread already dead\n");
162 /* Set the special reply value so we don't reply this message back */
163 *ReplyCode
= CsrReplyDeadClient
;
168 /* Check for other failures */
169 if (!NT_SUCCESS(Status
))
171 DPRINT1("Failed to create process/thread structures: %lx\n", Status
);
175 /* Call the user notification procedure */
176 if (UserNotifyProcessCreate
)
178 UserNotifyProcessCreate(CreateProcessRequest
->ClientId
.UniqueProcess
,
179 Process
->ClientId
.UniqueThread
,
184 /* Check if this is a VDM process */
185 if (CreateProcessRequest
->VdmBinaryType
)
187 PVDM_CONSOLE_RECORD ConsoleRecord
;
189 if (CreateProcessRequest
->VdmTask
!= 0)
191 /* Get the console record using the task ID */
192 Status
= GetConsoleRecordBySessionId(CreateProcessRequest
->VdmTask
,
197 /* Get the console record using the console handle */
198 Status
= BaseSrvGetConsoleRecord(CreateProcessRequest
->hVDM
,
202 /* Check if it failed */
203 if (!NT_SUCCESS(Status
)) return Status
;
205 /* Store the process ID of the VDM in the console record */
206 ConsoleRecord
->ProcessId
= HandleToUlong(CreateProcessRequest
->ClientId
.UniqueProcess
);
209 /* Return the result of this operation */
213 CSR_API(BaseSrvCreateThread
)
216 PBASE_CREATE_THREAD CreateThreadRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.CreateThreadRequest
;
217 PCSR_THREAD CurrentThread
;
219 PCSR_PROCESS CsrProcess
;
221 /* Get the current CSR thread */
222 CurrentThread
= CsrGetClientThread();
225 DPRINT1("Server Thread TID: [%lx.%lx]\n",
226 CreateThreadRequest
->ClientId
.UniqueProcess
,
227 CreateThreadRequest
->ClientId
.UniqueThread
);
228 return STATUS_SUCCESS
; // server-to-server
231 /* Get the CSR Process for this request */
232 CsrProcess
= CurrentThread
->Process
;
233 if (CsrProcess
->ClientId
.UniqueProcess
!=
234 CreateThreadRequest
->ClientId
.UniqueProcess
)
236 /* This is a remote thread request -- is it within the server itself? */
237 if (CreateThreadRequest
->ClientId
.UniqueProcess
== NtCurrentTeb()->ClientId
.UniqueProcess
)
239 /* Accept this without any further work */
240 return STATUS_SUCCESS
;
243 /* Get the real CSR Process for the remote thread's process */
244 Status
= CsrLockProcessByClientId(CreateThreadRequest
->ClientId
.UniqueProcess
,
246 if (!NT_SUCCESS(Status
)) return Status
;
249 /* Duplicate the thread handle so we can own it */
250 Status
= NtDuplicateObject(CurrentThread
->Process
->ProcessHandle
,
251 CreateThreadRequest
->ThreadHandle
,
256 DUPLICATE_SAME_ACCESS
);
257 if (NT_SUCCESS(Status
))
259 /* Call CSRSRV to tell it about the new thread */
260 Status
= CsrCreateThread(CsrProcess
,
262 &CreateThreadRequest
->ClientId
,
266 /* Unlock the process and return */
267 if (CsrProcess
!= CurrentThread
->Process
) CsrUnlockProcess(CsrProcess
);
271 CSR_API(BaseSrvExitProcess
)
273 PCSR_THREAD CsrThread
= CsrGetClientThread();
274 ASSERT(CsrThread
!= NULL
);
276 /* Set the special reply value so we don't reply this message back */
277 *ReplyCode
= CsrReplyDeadClient
;
279 /* Remove the CSR_THREADs and CSR_PROCESS */
280 return CsrDestroyProcess(&CsrThread
->ClientId
,
281 (NTSTATUS
)((PBASE_API_MESSAGE
)ApiMessage
)->Data
.ExitProcessRequest
.uExitCode
);
284 CSR_API(BaseSrvGetProcessShutdownParam
)
286 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.ShutdownParametersRequest
;
287 PCSR_THREAD CsrThread
= CsrGetClientThread();
290 ShutdownParametersRequest
->ShutdownLevel
= CsrThread
->Process
->ShutdownLevel
;
291 /* Only SHUTDOWN_NORETRY flag is valid for this API. The other private flags are for CSRSRV/WINSRV only. */
292 ShutdownParametersRequest
->ShutdownFlags
= CsrThread
->Process
->ShutdownFlags
& SHUTDOWN_NORETRY
;
294 return STATUS_SUCCESS
;
297 CSR_API(BaseSrvSetProcessShutdownParam
)
299 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest
= &((PBASE_API_MESSAGE
)ApiMessage
)->Data
.ShutdownParametersRequest
;
300 PCSR_THREAD CsrThread
= CsrGetClientThread();
303 /* Only SHUTDOWN_NORETRY flag is valid for this API. The other private flags are for CSRSRV/WINSRV only. */
304 if (ShutdownParametersRequest
->ShutdownFlags
& ~SHUTDOWN_NORETRY
)
306 /* If there were other flags specified, fail the call */
307 return STATUS_INVALID_PARAMETER
;
310 CsrThread
->Process
->ShutdownLevel
= ShutdownParametersRequest
->ShutdownLevel
;
311 /* Notice that all the possible other private flags are reinitialized here */
312 CsrThread
->Process
->ShutdownFlags
= ShutdownParametersRequest
->ShutdownFlags
;
314 return STATUS_SUCCESS
;
317 /* PUBLIC API *****************************************************************/
321 BaseSetProcessCreateNotify(IN BASE_PROCESS_CREATE_NOTIFY_ROUTINE ProcessCreateNotifyProc
)
323 /* Set the user notification procedure to be called when a process is created */
324 UserNotifyProcessCreate
= ProcessCreateNotifyProc
;