[REACTOS]
[reactos.git] / reactos / deprecated / csrsrv / api / process.c
1 /*
2 * subsystems/win32/csrss/csrsrv/api/process.c
3 *
4 * "\windows\ApiPort" port process management functions
5 *
6 * ReactOS Operating System
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <srv.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 extern NTSTATUS CallProcessCreated(PCSR_PROCESS, PCSR_PROCESS);
17
18 /* GLOBALS *******************************************************************/
19
20 /* FUNCTIONS *****************************************************************/
21
22 /**********************************************************************
23 * CSRSS API
24 *********************************************************************/
25
26 CSR_API(CsrSrvCreateProcess)
27 {
28 NTSTATUS Status;
29 HANDLE ProcessHandle, ThreadHandle;
30 PCSR_THREAD CsrThread;
31 PCSR_PROCESS NewProcessData;
32 ULONG Flags, VdmPower = 0, DebugFlags = 0;
33
34 /* Get the current client thread */
35 CsrThread = NtCurrentTeb()->CsrClientThread;
36 ASSERT(CsrThread != NULL);
37
38 /* Extract the flags out of the process handle */
39 Flags = (ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & 3;
40 Request->Data.CreateProcessRequest.ProcessHandle = (HANDLE)((ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & ~3);
41
42 /* Duplicate the process handle */
43 Status = NtDuplicateObject(CsrThread->Process->ProcessHandle,
44 Request->Data.CreateProcessRequest.ProcessHandle,
45 NtCurrentProcess(),
46 &ProcessHandle,
47 0,
48 0,
49 DUPLICATE_SAME_ACCESS);
50 if (!NT_SUCCESS(Status))
51 {
52 DPRINT1("Failed to duplicate process handle\n");
53 return Status;
54 }
55
56 /* Duplicate the thread handle */
57 Status = NtDuplicateObject(CsrThread->Process->ProcessHandle,
58 Request->Data.CreateProcessRequest.ThreadHandle,
59 NtCurrentProcess(),
60 &ThreadHandle,
61 0,
62 0,
63 DUPLICATE_SAME_ACCESS);
64 if (!NT_SUCCESS(Status))
65 {
66 DPRINT1("Failed to duplicate process handle\n");
67 NtClose(ProcessHandle);
68 return Status;
69 }
70
71 /* See if this is a VDM process */
72 if (VdmPower)
73 {
74 /* Request VDM powers */
75 Status = NtSetInformationProcess(ProcessHandle,
76 ProcessWx86Information,
77 &VdmPower,
78 sizeof(VdmPower));
79 if (!NT_SUCCESS(Status))
80 {
81 DPRINT1("Failed to get VDM powers\n");
82 NtClose(ProcessHandle);
83 NtClose(ThreadHandle);
84 return Status;
85 }
86 }
87
88 /* Convert some flags. FIXME: More need conversion */
89 if (Request->Data.CreateProcessRequest.CreationFlags & CREATE_NEW_PROCESS_GROUP)
90 {
91 DebugFlags |= CsrProcessCreateNewGroup;
92 }
93
94 /* FIXME: SxS Stuff */
95
96 /* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
97 Status = CsrCreateProcess(ProcessHandle,
98 ThreadHandle,
99 &Request->Data.CreateProcessRequest.ClientId,
100 CsrThread->Process->NtSession,
101 DebugFlags,
102 NULL);
103 if (Status == STATUS_THREAD_IS_TERMINATING)
104 {
105 DPRINT1("Thread already dead\n");
106 return Status;
107 }
108
109 /* Check for other failures */
110 if (!NT_SUCCESS(Status))
111 {
112 DPRINT1("Failed to create process/thread structures: %lx\n", Status);
113 return Status;
114 }
115
116 /* FIXME: Should notify user32 */
117
118 /* FIXME: VDM vodoo */
119
120 /* ReactOS Compatibility */
121 Status = CsrLockProcessByClientId(Request->Data.CreateProcessRequest.ClientId.UniqueProcess, &NewProcessData);
122 ASSERT(Status == STATUS_SUCCESS);
123 if (!(Request->Data.CreateProcessRequest.CreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
124 {
125 NewProcessData->ParentConsole = ProcessData->Console;
126 NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles;
127 }
128 RtlInitializeCriticalSection(&NewProcessData->HandleTableLock);
129 CallProcessCreated(ProcessData, NewProcessData);
130 CsrUnlockProcess(NewProcessData);
131
132 /* Return the result of this operation */
133 return Status;
134 }
135
136 CSR_API(CsrSrvCreateThread)
137 {
138 PCSR_THREAD CurrentThread;
139 HANDLE ThreadHandle;
140 NTSTATUS Status;
141 PCSR_PROCESS CsrProcess;
142
143 /* Get the current CSR thread */
144 CurrentThread = NtCurrentTeb()->CsrClientThread;
145 if (!CurrentThread)
146 {
147 DPRINT1("Server Thread TID: [%lx.%lx]\n",
148 Request->Data.CreateThreadRequest.ClientId.UniqueProcess,
149 Request->Data.CreateThreadRequest.ClientId.UniqueThread);
150 return STATUS_SUCCESS; // server-to-server
151 }
152
153 /* Get the CSR Process for this request */
154 CsrProcess = CurrentThread->Process;
155 if (CsrProcess->ClientId.UniqueProcess !=
156 Request->Data.CreateThreadRequest.ClientId.UniqueProcess)
157 {
158 /* This is a remote thread request -- is it within the server itself? */
159 if (Request->Data.CreateThreadRequest.ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
160 {
161 /* Accept this without any further work */
162 return STATUS_SUCCESS;
163 }
164
165 /* Get the real CSR Process for the remote thread's process */
166 Status = CsrLockProcessByClientId(Request->Data.CreateThreadRequest.ClientId.UniqueProcess,
167 &CsrProcess);
168 if (!NT_SUCCESS(Status)) return Status;
169 }
170
171 /* Duplicate the thread handle so we can own it */
172 Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
173 Request->Data.CreateThreadRequest.ThreadHandle,
174 NtCurrentProcess(),
175 &ThreadHandle,
176 0,
177 0,
178 DUPLICATE_SAME_ACCESS);
179 if (NT_SUCCESS(Status))
180 {
181 /* Call CSRSRV to tell it about the new thread */
182 Status = CsrCreateThread(CsrProcess,
183 ThreadHandle,
184 &Request->Data.CreateThreadRequest.ClientId);
185 }
186
187 /* Unlock the process and return */
188 if (CsrProcess != CurrentThread->Process) CsrUnlockProcess(CsrProcess);
189 return Status;
190 }
191
192 CSR_API(CsrTerminateProcess)
193 {
194 PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread;
195 ASSERT(CsrThread != NULL);
196
197 /* Set magic flag so we don't reply this message back */
198 Request->Type = 0xBABE;
199
200 /* Remove the CSR_THREADs and CSR_PROCESS */
201 return CsrDestroyProcess(&CsrThread->ClientId,
202 (NTSTATUS)Request->Data.TerminateProcessRequest.uExitCode);
203 }
204
205 CSR_API(CsrConnectProcess)
206 {
207
208 return(STATUS_SUCCESS);
209 }
210
211 CSR_API(CsrGetShutdownParameters)
212 {
213
214 Request->Data.GetShutdownParametersRequest.Level = ProcessData->ShutdownLevel;
215 Request->Data.GetShutdownParametersRequest.Flags = ProcessData->ShutdownFlags;
216
217 return(STATUS_SUCCESS);
218 }
219
220 CSR_API(CsrSetShutdownParameters)
221 {
222
223 ProcessData->ShutdownLevel = Request->Data.SetShutdownParametersRequest.Level;
224 ProcessData->ShutdownFlags = Request->Data.SetShutdownParametersRequest.Flags;
225
226 return(STATUS_SUCCESS);
227 }
228
229 /* EOF */