3 * reactos/subsys/csrss/api/process.c
5 * "\windows\ApiPort" port process management functions
7 * ReactOS Operating System
10 /* INCLUDES ******************************************************************/
17 #define LOCK RtlEnterCriticalSection(&ProcessDataLock)
18 #define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
20 /* GLOBALS *******************************************************************/
22 static ULONG NrProcess
;
23 static PCSRSS_PROCESS_DATA ProcessData
[256];
24 RTL_CRITICAL_SECTION ProcessDataLock
;
26 /* FUNCTIONS *****************************************************************/
28 VOID STDCALL
CsrInitProcessData(VOID
)
30 RtlZeroMemory (ProcessData
, sizeof ProcessData
);
31 NrProcess
= sizeof ProcessData
/ sizeof ProcessData
[0];
32 RtlInitializeCriticalSection( &ProcessDataLock
);
35 PCSRSS_PROCESS_DATA STDCALL
CsrGetProcessData(HANDLE ProcessId
)
38 PCSRSS_PROCESS_DATA pProcessData
;
40 hash
= (ULONG_PTR
)ProcessId
% (sizeof(ProcessData
) / sizeof(*ProcessData
));
44 pProcessData
= ProcessData
[hash
];
46 while (pProcessData
&& pProcessData
->ProcessId
!= ProcessId
)
48 pProcessData
= pProcessData
->next
;
54 PCSRSS_PROCESS_DATA STDCALL
CsrCreateProcessData(HANDLE ProcessId
)
57 PCSRSS_PROCESS_DATA pProcessData
;
58 OBJECT_ATTRIBUTES ObjectAttributes
;
62 hash
= (ULONG_PTR
)ProcessId
% (sizeof(ProcessData
) / sizeof(*ProcessData
));
66 pProcessData
= ProcessData
[hash
];
68 while (pProcessData
&& pProcessData
->ProcessId
!= ProcessId
)
70 pProcessData
= pProcessData
->next
;
72 if (pProcessData
== NULL
)
74 pProcessData
= RtlAllocateHeap(CsrssApiHeap
,
76 sizeof(CSRSS_PROCESS_DATA
));
79 pProcessData
->ProcessId
= ProcessId
;
80 pProcessData
->next
= ProcessData
[hash
];
81 ProcessData
[hash
] = pProcessData
;
83 ClientId
.UniqueThread
= NULL
;
84 ClientId
.UniqueProcess
= pProcessData
->ProcessId
;
85 InitializeObjectAttributes(&ObjectAttributes
,
91 /* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
92 Status
= NtOpenProcess(&pProcessData
->Process
,
93 PROCESS_DUP_HANDLE
| PROCESS_VM_OPERATION
|
94 PROCESS_VM_WRITE
| PROCESS_CREATE_THREAD
| SYNCHRONIZE
,
97 if (!NT_SUCCESS(Status
))
99 ProcessData
[hash
] = pProcessData
->next
;
100 RtlFreeHeap(CsrssApiHeap
, 0, pProcessData
);
103 RtlInitializeCriticalSection(&pProcessData
->HandleTableLock
);
108 DPRINT("Process data for pid %d already exist\n", ProcessId
);
111 if (pProcessData
== NULL
)
113 DbgPrint("CSR: CsrGetProcessData() failed\n");
118 NTSTATUS STDCALL
CsrFreeProcessData(HANDLE Pid
)
122 PCSRSS_PROCESS_DATA pProcessData
, pPrevProcessData
= NULL
;
124 hash
= (ULONG_PTR
)Pid
% (sizeof(ProcessData
) / sizeof(*ProcessData
));
128 pProcessData
= ProcessData
[hash
];
130 while (pProcessData
&& pProcessData
->ProcessId
!= Pid
)
132 pPrevProcessData
= pProcessData
;
133 pProcessData
= pProcessData
->next
;
138 DPRINT("CsrFreeProcessData pid: %d\n", Pid
);
139 if (pProcessData
->Process
)
141 NtClose(pProcessData
->Process
);
143 if (pProcessData
->Console
)
145 RtlEnterCriticalSection(&ProcessDataLock
);
146 RemoveEntryList(&pProcessData
->ProcessEntry
);
147 RtlLeaveCriticalSection(&ProcessDataLock
);
149 if (pProcessData
->HandleTable
)
151 for (c
= 0; c
< pProcessData
->HandleTableSize
; c
++)
153 if (pProcessData
->HandleTable
[c
])
155 CsrReleaseObject(pProcessData
, (HANDLE
)(((c
+ 1) << 2)|0x3));
158 RtlFreeHeap(CsrssApiHeap
, 0, pProcessData
->HandleTable
);
160 RtlDeleteCriticalSection(&pProcessData
->HandleTableLock
);
161 if (pProcessData
->Console
)
163 CsrReleaseObjectByPointer((Object_t
*) pProcessData
->Console
);
165 if (pProcessData
->CsrSectionViewBase
)
167 NtUnmapViewOfSection(NtCurrentProcess(), pProcessData
->CsrSectionViewBase
);
169 if (pPrevProcessData
)
171 pPrevProcessData
->next
= pProcessData
->next
;
175 ProcessData
[hash
] = pProcessData
->next
;
178 RtlFreeHeap(CsrssApiHeap
, 0, pProcessData
);
180 return STATUS_SUCCESS
;
184 return STATUS_INVALID_PARAMETER
;
188 /**********************************************************************
190 *********************************************************************/
192 CSR_API(CsrCreateProcess
)
194 PCSRSS_PROCESS_DATA NewProcessData
;
196 CSR_API_MESSAGE ApiRequest
;
198 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
199 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
201 NewProcessData
= CsrCreateProcessData(Request
->Data
.CreateProcessRequest
.NewProcessId
);
202 if (NewProcessData
== NULL
)
204 Request
->Status
= STATUS_NO_MEMORY
;
205 return(STATUS_NO_MEMORY
);
208 /* Set default shutdown parameters */
209 NewProcessData
->ShutdownLevel
= 0x280;
210 NewProcessData
->ShutdownFlags
= 0;
212 if (Request
->Data
.CreateProcessRequest
.Flags
& DETACHED_PROCESS
)
214 NewProcessData
->Console
= NULL
;
216 else if (Request
->Data
.CreateProcessRequest
.Flags
& CREATE_NEW_CONSOLE
)
218 ApiRequest
.Type
= ALLOC_CONSOLE
;
219 ApiRequest
.Header
.DataSize
= sizeof(CSRSS_ALLOC_CONSOLE
);
220 ApiRequest
.Header
.MessageSize
= LPC_MESSAGE_BASE_SIZE
+ sizeof(CSRSS_ALLOC_CONSOLE
);
221 ApiRequest
.Data
.AllocConsoleRequest
.CtrlDispatcher
= Request
->Data
.CreateProcessRequest
.CtrlDispatcher
;
223 CsrApiCallHandler(NewProcessData
, &ApiRequest
);
225 Request
->Status
= ApiRequest
.Status
;
226 if (! NT_SUCCESS(Request
->Status
))
228 CsrFreeProcessData(Request
->Data
.CreateProcessRequest
.NewProcessId
);
229 return Request
->Status
;
231 Request
->Data
.CreateProcessRequest
.InputHandle
= ApiRequest
.Data
.AllocConsoleRequest
.InputHandle
;
232 Request
->Data
.CreateProcessRequest
.OutputHandle
= ApiRequest
.Data
.AllocConsoleRequest
.OutputHandle
;
236 NewProcessData
->Console
= ProcessData
->Console
;
237 InterlockedIncrement( &(ProcessData
->Console
->Header
.ReferenceCount
) );
238 CsrInsertObject(NewProcessData
,
239 &Request
->Data
.CreateProcessRequest
.InputHandle
,
240 (Object_t
*)NewProcessData
->Console
);
241 RtlEnterCriticalSection(&ProcessDataLock
);
242 CsrInsertObject( NewProcessData
,
243 &Request
->Data
.CreateProcessRequest
.OutputHandle
,
244 &(NewProcessData
->Console
->ActiveBuffer
->Header
) );
246 RtlLeaveCriticalSection(&ProcessDataLock
);
247 Status
= NtDuplicateObject( NtCurrentProcess(), NewProcessData
->Console
->ActiveEvent
, NewProcessData
->Process
, &NewProcessData
->ConsoleEvent
, SYNCHRONIZE
, FALSE
, 0 );
248 if( !NT_SUCCESS( Status
) )
250 DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status
);
251 CsrFreeProcessData( NewProcessData
->ProcessId
);
252 Request
->Status
= Status
;
255 NewProcessData
->CtrlDispatcher
= Request
->Data
.CreateProcessRequest
.CtrlDispatcher
;
256 RtlEnterCriticalSection(&ProcessDataLock
);
257 InsertHeadList(&NewProcessData
->Console
->ProcessList
, &NewProcessData
->ProcessEntry
);
258 RtlLeaveCriticalSection(&ProcessDataLock
);
261 Request
->Data
.CreateProcessRequest
.Console
= NewProcessData
->Console
;
263 Request
->Status
= STATUS_SUCCESS
;
264 return(STATUS_SUCCESS
);
267 CSR_API(CsrTerminateProcess
)
269 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
270 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
);
272 if (ProcessData
== NULL
)
274 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
277 Request
->Status
= STATUS_SUCCESS
;
278 return STATUS_SUCCESS
;
281 CSR_API(CsrConnectProcess
)
283 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
284 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
286 Request
->Status
= STATUS_SUCCESS
;
288 return(STATUS_SUCCESS
);
291 CSR_API(CsrGetShutdownParameters
)
293 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
294 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
296 if (ProcessData
== NULL
)
298 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
301 Request
->Data
.GetShutdownParametersRequest
.Level
= ProcessData
->ShutdownLevel
;
302 Request
->Data
.GetShutdownParametersRequest
.Flags
= ProcessData
->ShutdownFlags
;
304 Request
->Status
= STATUS_SUCCESS
;
306 return(STATUS_SUCCESS
);
309 CSR_API(CsrSetShutdownParameters
)
311 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
312 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
314 if (ProcessData
== NULL
)
316 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
319 ProcessData
->ShutdownLevel
= Request
->Data
.SetShutdownParametersRequest
.Level
;
320 ProcessData
->ShutdownFlags
= Request
->Data
.SetShutdownParametersRequest
.Flags
;
322 Request
->Status
= STATUS_SUCCESS
;
324 return(STATUS_SUCCESS
);
327 CSR_API(CsrGetInputHandle
)
329 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
330 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
332 if (ProcessData
== NULL
)
334 Request
->Data
.GetInputHandleRequest
.InputHandle
= INVALID_HANDLE_VALUE
;
335 Request
->Status
= STATUS_INVALID_PARAMETER
;
337 else if (ProcessData
->Console
)
339 Request
->Status
= CsrInsertObject(ProcessData
,
340 &Request
->Data
.GetInputHandleRequest
.InputHandle
,
341 (Object_t
*)ProcessData
->Console
);
345 Request
->Data
.GetInputHandleRequest
.InputHandle
= INVALID_HANDLE_VALUE
;
346 Request
->Status
= STATUS_SUCCESS
;
349 return Request
->Status
;
352 CSR_API(CsrGetOutputHandle
)
354 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
355 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
357 if (ProcessData
== NULL
)
359 Request
->Data
.GetOutputHandleRequest
.OutputHandle
= INVALID_HANDLE_VALUE
;
360 Request
->Status
= STATUS_INVALID_PARAMETER
;
362 else if (ProcessData
->Console
)
364 RtlEnterCriticalSection(&ProcessDataLock
);
365 Request
->Status
= CsrInsertObject(ProcessData
,
366 &Request
->Data
.GetOutputHandleRequest
.OutputHandle
,
367 &(ProcessData
->Console
->ActiveBuffer
->Header
));
368 RtlLeaveCriticalSection(&ProcessDataLock
);
372 Request
->Data
.GetOutputHandleRequest
.OutputHandle
= INVALID_HANDLE_VALUE
;
373 Request
->Status
= STATUS_SUCCESS
;
376 return Request
->Status
;
379 CSR_API(CsrCloseHandle
)
381 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
382 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
384 if (ProcessData
== NULL
)
386 Request
->Status
= STATUS_INVALID_PARAMETER
;
390 Request
->Status
= CsrReleaseObject(ProcessData
, Request
->Data
.CloseHandleRequest
.Handle
);
392 return Request
->Status
;
395 CSR_API(CsrVerifyHandle
)
397 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
398 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
400 Request
->Status
= CsrVerifyObject(ProcessData
, Request
->Data
.VerifyHandleRequest
.Handle
);
401 if (!NT_SUCCESS(Request
->Status
))
403 DPRINT("CsrVerifyObject failed, status=%x\n", Request
->Status
);
406 return Request
->Status
;
409 CSR_API(CsrDuplicateHandle
)
413 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
414 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
416 ProcessData
= CsrGetProcessData(Request
->Data
.DuplicateHandleRequest
.ProcessId
);
417 Request
->Status
= CsrGetObject(ProcessData
, Request
->Data
.DuplicateHandleRequest
.Handle
, &Object
);
418 if (! NT_SUCCESS(Request
->Status
))
420 DPRINT("CsrGetObject failed, status=%x\n", Request
->Status
);
424 Request
->Status
= CsrInsertObject(ProcessData
,
425 &Request
->Data
.DuplicateHandleRequest
.Handle
,
428 return Request
->Status
;
431 CSR_API(CsrGetInputWaitHandle
)
433 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
434 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
436 if (ProcessData
== NULL
)
439 Request
->Data
.GetConsoleInputWaitHandle
.InputWaitHandle
= INVALID_HANDLE_VALUE
;
440 Request
->Status
= STATUS_INVALID_PARAMETER
;
444 Request
->Data
.GetConsoleInputWaitHandle
.InputWaitHandle
= ProcessData
->ConsoleEvent
;
445 Request
->Status
= STATUS_SUCCESS
;
447 return Request
->Status
;