ReactOS  0.4.14-dev-323-g6fe6a88
proc.c
Go to the documentation of this file.
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 #include "vdm.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* GLOBALS ********************************************************************/
18 
19 /* User notification procedure to be called when a process is created */
21 
22 /* PUBLIC SERVER APIS *********************************************************/
23 
24 CSR_API(BaseSrvDebugProcess)
25 {
26  /* Deprecated */
27  return STATUS_UNSUCCESSFUL;
28 }
29 
30 CSR_API(BaseSrvRegisterThread)
31 {
32  DPRINT1("%s not yet implemented\n", __FUNCTION__);
34 }
35 
36 CSR_API(BaseSrvSxsCreateActivationContext)
37 {
38  DPRINT1("%s not yet implemented\n", __FUNCTION__);
40 }
41 
42 CSR_API(BaseSrvSetTermsrvAppInstallMode)
43 {
44  DPRINT1("%s not yet implemented\n", __FUNCTION__);
46 }
47 
48 CSR_API(BaseSrvSetTermsrvClientTimeZone)
49 {
50  DPRINT1("%s not yet implemented\n", __FUNCTION__);
52 }
53 
54 CSR_API(BaseSrvGetTempFile)
55 {
56  static UINT BaseGetTempFileUnique = 0;
57  PBASE_GET_TEMP_FILE GetTempFile = &((PBASE_API_MESSAGE)ApiMessage)->Data.GetTempFileRequest;
58 
59  /* Return 16-bits ID */
60  GetTempFile->UniqueID = (++BaseGetTempFileUnique & 0xFFFF);
61 
62  DPRINT("Returning: %u\n", GetTempFile->UniqueID);
63 
64  return GetTempFile->UniqueID;
65 }
66 
67 CSR_API(BaseSrvCreateProcess)
68 {
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;
75 
76  /* Get the current client thread */
77  CsrThread = CsrGetClientThread();
78  ASSERT(CsrThread != NULL);
79 
80  Process = CsrThread->Process;
81 
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);
85 
86  /* Some things should be done if this is a VDM process */
87  if (CreateProcessRequest->VdmBinaryType)
88  {
89  /* We need to set the VDM power later on */
90  VdmPower = 1;
91  }
92 
93  /* Duplicate the process handle */
94  Status = NtDuplicateObject(Process->ProcessHandle,
95  CreateProcessRequest->ProcessHandle,
98  0,
99  0,
101  if (!NT_SUCCESS(Status))
102  {
103  DPRINT1("Failed to duplicate process handle: %lx\n", Status);
104  return Status;
105  }
106 
107  /* Duplicate the thread handle */
108  Status = NtDuplicateObject(Process->ProcessHandle,
109  CreateProcessRequest->ThreadHandle,
111  &ThreadHandle,
112  0,
113  0,
115  if (!NT_SUCCESS(Status))
116  {
117  DPRINT1("Failed to duplicate thread handle: %lx\n", Status);
119  return Status;
120  }
121 
122  /* If this is a VDM process, request VDM power */
123  if (VdmPower)
124  {
127  &VdmPower,
128  sizeof(VdmPower));
129  if (!NT_SUCCESS(Status))
130  {
131  DPRINT1("Failed to get VDM powers\n");
133  NtClose(ThreadHandle);
134  return Status;
135  }
136  }
137 
138  /* Flags conversion. FIXME: More need conversion */
139  if (CreateProcessRequest->CreationFlags & CREATE_NEW_PROCESS_GROUP)
140  {
141  DebugFlags |= CsrProcessCreateNewGroup;
142  }
143  if ((Flags & 2) == 0)
144  {
145  /* We are launching a console process */
146  DebugFlags |= CsrProcessIsConsoleApp;
147  }
148 
149  /* FIXME: SxS Stuff */
150 
151  /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
153  ThreadHandle,
154  &CreateProcessRequest->ClientId,
155  Process->NtSession,
156  DebugFlags,
157  NULL);
159  {
160  DPRINT1("Thread already dead\n");
161 
162  /* Set the special reply value so we don't reply this message back */
163  *ReplyCode = CsrReplyDeadClient;
164 
165  return Status;
166  }
167 
168  /* Check for other failures */
169  if (!NT_SUCCESS(Status))
170  {
171  DPRINT1("Failed to create process/thread structures: %lx\n", Status);
172  return Status;
173  }
174 
175  /* Call the user notification procedure */
177  {
178  UserNotifyProcessCreate(CreateProcessRequest->ClientId.UniqueProcess,
179  Process->ClientId.UniqueThread,
180  0,
181  Flags);
182  }
183 
184  /* Check if this is a VDM process */
185  if (CreateProcessRequest->VdmBinaryType)
186  {
187  PVDM_CONSOLE_RECORD ConsoleRecord;
188 
189  if (CreateProcessRequest->VdmTask != 0)
190  {
191  /* Get the console record using the task ID */
192  Status = GetConsoleRecordBySessionId(CreateProcessRequest->VdmTask,
193  &ConsoleRecord);
194  }
195  else
196  {
197  /* Get the console record using the console handle */
198  Status = BaseSrvGetConsoleRecord(CreateProcessRequest->hVDM,
199  &ConsoleRecord);
200  }
201 
202  /* Check if it failed */
203  if (!NT_SUCCESS(Status)) return Status;
204 
205  /* Store the process ID of the VDM in the console record */
206  ConsoleRecord->ProcessId = HandleToUlong(CreateProcessRequest->ClientId.UniqueProcess);
207  }
208 
209  /* Return the result of this operation */
210  return Status;
211 }
212 
213 CSR_API(BaseSrvCreateThread)
214 {
216  PBASE_CREATE_THREAD CreateThreadRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CreateThreadRequest;
217  PCSR_THREAD CurrentThread;
218  HANDLE ThreadHandle;
219  PCSR_PROCESS CsrProcess;
220 
221  /* Get the current CSR thread */
222  CurrentThread = CsrGetClientThread();
223  if (!CurrentThread)
224  {
225  DPRINT1("Server Thread TID: [%lx.%lx]\n",
226  CreateThreadRequest->ClientId.UniqueProcess,
227  CreateThreadRequest->ClientId.UniqueThread);
228  return STATUS_SUCCESS; // server-to-server
229  }
230 
231  /* Get the CSR Process for this request */
232  CsrProcess = CurrentThread->Process;
233  if (CsrProcess->ClientId.UniqueProcess !=
234  CreateThreadRequest->ClientId.UniqueProcess)
235  {
236  /* This is a remote thread request -- is it within the server itself? */
237  if (CreateThreadRequest->ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
238  {
239  /* Accept this without any further work */
240  return STATUS_SUCCESS;
241  }
242 
243  /* Get the real CSR Process for the remote thread's process */
244  Status = CsrLockProcessByClientId(CreateThreadRequest->ClientId.UniqueProcess,
245  &CsrProcess);
246  if (!NT_SUCCESS(Status)) return Status;
247  }
248 
249  /* Duplicate the thread handle so we can own it */
250  Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
251  CreateThreadRequest->ThreadHandle,
253  &ThreadHandle,
254  0,
255  0,
257  if (NT_SUCCESS(Status))
258  {
259  /* Call CSRSRV to tell it about the new thread */
260  Status = CsrCreateThread(CsrProcess,
261  ThreadHandle,
262  &CreateThreadRequest->ClientId,
263  TRUE);
264  }
265 
266  /* Unlock the process and return */
267  if (CsrProcess != CurrentThread->Process) CsrUnlockProcess(CsrProcess);
268  return Status;
269 }
270 
271 CSR_API(BaseSrvExitProcess)
272 {
273  PCSR_THREAD CsrThread = CsrGetClientThread();
274  ASSERT(CsrThread != NULL);
275 
276  /* Set the special reply value so we don't reply this message back */
277  *ReplyCode = CsrReplyDeadClient;
278 
279  /* Remove the CSR_THREADs and CSR_PROCESS */
280  return CsrDestroyProcess(&CsrThread->ClientId,
281  (NTSTATUS)((PBASE_API_MESSAGE)ApiMessage)->Data.ExitProcessRequest.uExitCode);
282 }
283 
284 CSR_API(BaseSrvGetProcessShutdownParam)
285 {
286  PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ShutdownParametersRequest;
287  PCSR_THREAD CsrThread = CsrGetClientThread();
288  ASSERT(CsrThread);
289 
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;
293 
294  return STATUS_SUCCESS;
295 }
296 
297 CSR_API(BaseSrvSetProcessShutdownParam)
298 {
299  PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ShutdownParametersRequest;
300  PCSR_THREAD CsrThread = CsrGetClientThread();
301  ASSERT(CsrThread);
302 
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)
305  {
306  /* If there were other flags specified, fail the call */
308  }
309 
310  CsrThread->Process->ShutdownLevel = ShutdownParametersRequest->ShutdownLevel;
311  /* Notice that all the possible other private flags are reinitialized here */
312  CsrThread->Process->ShutdownFlags = ShutdownParametersRequest->ShutdownFlags;
313 
314  return STATUS_SUCCESS;
315 }
316 
317 /* PUBLIC API *****************************************************************/
318 
319 VOID
320 NTAPI
322 {
323  /* Set the user notification procedure to be called when a process is created */
324  UserNotifyProcessCreate = ProcessCreateNotifyProc;
325 }
326 
327 /* EOF */
#define IN
Definition: typedefs.h:38
#define CsrGetClientThread()
Definition: csrsrv.h:77
#define TRUE
Definition: types.h:120
NTSTATUS BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:49
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:297
LONG NTSTATUS
Definition: precomp.h:26
#define HandleToUlong(h)
Definition: basetsd.h:79
ULONG ShutdownFlags
Definition: csrsrv.h:59
NTSTATUS NTAPI CsrDestroyProcess(IN PCLIENT_ID Cid, IN NTSTATUS ExitStatus)
Definition: procsup.c:734
HANDLE UniqueProcess
Definition: compat.h:474
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:185
VOID NTAPI BaseSetProcessCreateNotify(IN BASE_PROCESS_CREATE_NOTIFY_ROUTINE ProcessCreateNotifyProc)
Definition: proc.c:321
static BASE_PROCESS_CREATE_NOTIFY_ROUTINE UserNotifyProcessCreate
Definition: proc.c:20
HANDLE ThreadHandle
Definition: basemsg.h:90
PCSR_PROCESS Process
Definition: csrsrv.h:69
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define DUPLICATE_SAME_ACCESS
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:95
struct _BASE_API_MESSAGE * PBASE_API_MESSAGE
HANDLE ProcessHandle
Definition: csrsrv.h:46
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSR_PROCESS *CsrProcess OPTIONAL)
void DPRINT(...)
Definition: polytest.cpp:61
HANDLE ThreadHandle
Definition: basemsg.h:104
CLIENT_ID ClientId
Definition: csrsrv.h:38
#define NtCurrentProcess()
Definition: nt_native.h:1657
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CLIENT_ID ClientId
Definition: csrsrv.h:68
ULONG ProcessId
Definition: vdm.h:26
CLIENT_ID ClientId
Definition: basemsg.h:105
HANDLE ProcessHandle
Definition: basemsg.h:89
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
NTSTATUS NTAPI CsrCreateThread(IN PCSR_PROCESS CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId, IN BOOLEAN HaveClient)
Definition: thredsup.c:677
HANDLE UniqueThread
Definition: compat.h:475
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
BOOL(NTAPI * BASE_PROCESS_CREATE_NOTIFY_ROUTINE)(HANDLE NewProcessId, HANDLE ParentThreadId, ULONG dwUnknown, ULONG CreateFlags)
Definition: base.h:16
Status
Definition: gdiplustypes.h:24
#define SHUTDOWN_NORETRY
Definition: winbase.h:429
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1112
unsigned int UINT
Definition: ndis.h:50
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3407
CLIENT_ID ClientId
Definition: basemsg.h:91
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
ULONG ShutdownLevel
Definition: csrsrv.h:58
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define __FUNCTION__
Definition: types.h:112
NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:1398
NTSTATUS NTAPI CsrCreateProcess(IN HANDLE hProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId, IN PCSR_NT_SESSION NtSession, IN ULONG Flags, IN PCLIENT_ID DebugCid)
Definition: procsup.c:421
CSR_API(BaseSrvDebugProcess)
Definition: proc.c:24