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
& ~0x3) % (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
& ~0x3) % (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
& ~0x3) % (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
;
197 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
198 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
200 NewProcessData
= CsrCreateProcessData(Request
->Data
.CreateProcessRequest
.NewProcessId
);
201 if (NewProcessData
== NULL
)
203 Request
->Status
= STATUS_NO_MEMORY
;
204 return(STATUS_NO_MEMORY
);
207 if (!(Request
->Data
.CreateProcessRequest
.Flags
& (CREATE_NEW_CONSOLE
|DETACHED_PROCESS
)))
209 NewProcessData
->ParentConsole
= ProcessData
->Console
;
210 NewProcessData
->bInheritHandles
= Request
->Data
.CreateProcessRequest
.bInheritHandles
;
211 if (Request
->Data
.CreateProcessRequest
.bInheritHandles
)
213 Status
= CsrDuplicateHandleTable(ProcessData
, NewProcessData
);
217 /* Set default shutdown parameters */
218 NewProcessData
->ShutdownLevel
= 0x280;
219 NewProcessData
->ShutdownFlags
= 0;
221 Request
->Status
= STATUS_SUCCESS
;
222 return(STATUS_SUCCESS
);
225 CSR_API(CsrTerminateProcess
)
227 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
228 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
);
230 if (ProcessData
== NULL
)
232 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
235 Request
->Status
= STATUS_SUCCESS
;
236 return STATUS_SUCCESS
;
239 CSR_API(CsrConnectProcess
)
241 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
242 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
244 Request
->Status
= STATUS_SUCCESS
;
246 return(STATUS_SUCCESS
);
249 CSR_API(CsrGetShutdownParameters
)
251 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
252 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
254 if (ProcessData
== NULL
)
256 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
259 Request
->Data
.GetShutdownParametersRequest
.Level
= ProcessData
->ShutdownLevel
;
260 Request
->Data
.GetShutdownParametersRequest
.Flags
= ProcessData
->ShutdownFlags
;
262 Request
->Status
= STATUS_SUCCESS
;
264 return(STATUS_SUCCESS
);
267 CSR_API(CsrSetShutdownParameters
)
269 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
270 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
272 if (ProcessData
== NULL
)
274 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
277 ProcessData
->ShutdownLevel
= Request
->Data
.SetShutdownParametersRequest
.Level
;
278 ProcessData
->ShutdownFlags
= Request
->Data
.SetShutdownParametersRequest
.Flags
;
280 Request
->Status
= STATUS_SUCCESS
;
282 return(STATUS_SUCCESS
);
285 CSR_API(CsrGetInputHandle
)
287 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
288 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
290 if (ProcessData
== NULL
)
292 Request
->Data
.GetInputHandleRequest
.InputHandle
= INVALID_HANDLE_VALUE
;
293 Request
->Status
= STATUS_INVALID_PARAMETER
;
295 else if (ProcessData
->Console
)
297 Request
->Status
= CsrInsertObject(ProcessData
,
298 &Request
->Data
.GetInputHandleRequest
.InputHandle
,
299 (Object_t
*)ProcessData
->Console
);
303 Request
->Data
.GetInputHandleRequest
.InputHandle
= INVALID_HANDLE_VALUE
;
304 Request
->Status
= STATUS_SUCCESS
;
307 return Request
->Status
;
310 CSR_API(CsrGetOutputHandle
)
312 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
313 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
315 if (ProcessData
== NULL
)
317 Request
->Data
.GetOutputHandleRequest
.OutputHandle
= INVALID_HANDLE_VALUE
;
318 Request
->Status
= STATUS_INVALID_PARAMETER
;
320 else if (ProcessData
->Console
)
322 RtlEnterCriticalSection(&ProcessDataLock
);
323 Request
->Status
= CsrInsertObject(ProcessData
,
324 &Request
->Data
.GetOutputHandleRequest
.OutputHandle
,
325 &(ProcessData
->Console
->ActiveBuffer
->Header
));
326 RtlLeaveCriticalSection(&ProcessDataLock
);
330 Request
->Data
.GetOutputHandleRequest
.OutputHandle
= INVALID_HANDLE_VALUE
;
331 Request
->Status
= STATUS_SUCCESS
;
334 return Request
->Status
;
337 CSR_API(CsrCloseHandle
)
339 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
340 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
342 if (ProcessData
== NULL
)
344 Request
->Status
= STATUS_INVALID_PARAMETER
;
348 Request
->Status
= CsrReleaseObject(ProcessData
, Request
->Data
.CloseHandleRequest
.Handle
);
350 return Request
->Status
;
353 CSR_API(CsrVerifyHandle
)
355 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
356 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
358 Request
->Status
= CsrVerifyObject(ProcessData
, Request
->Data
.VerifyHandleRequest
.Handle
);
359 if (!NT_SUCCESS(Request
->Status
))
361 DPRINT("CsrVerifyObject failed, status=%x\n", Request
->Status
);
364 return Request
->Status
;
367 CSR_API(CsrDuplicateHandle
)
371 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
372 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
374 ProcessData
= CsrGetProcessData(Request
->Data
.DuplicateHandleRequest
.ProcessId
);
375 Request
->Status
= CsrGetObject(ProcessData
, Request
->Data
.DuplicateHandleRequest
.Handle
, &Object
);
376 if (! NT_SUCCESS(Request
->Status
))
378 DPRINT("CsrGetObject failed, status=%x\n", Request
->Status
);
382 Request
->Status
= CsrInsertObject(ProcessData
,
383 &Request
->Data
.DuplicateHandleRequest
.Handle
,
386 return Request
->Status
;
389 CSR_API(CsrGetInputWaitHandle
)
391 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
392 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
394 if (ProcessData
== NULL
)
397 Request
->Data
.GetConsoleInputWaitHandle
.InputWaitHandle
= INVALID_HANDLE_VALUE
;
398 Request
->Status
= STATUS_INVALID_PARAMETER
;
402 Request
->Data
.GetConsoleInputWaitHandle
.InputWaitHandle
= ProcessData
->ConsoleEvent
;
403 Request
->Status
= STATUS_SUCCESS
;
405 return Request
->Status
;