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
;
196 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
197 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
199 NewProcessData
= CsrCreateProcessData(Request
->Data
.CreateProcessRequest
.NewProcessId
);
200 if (NewProcessData
== NULL
)
202 Request
->Status
= STATUS_NO_MEMORY
;
203 return(STATUS_NO_MEMORY
);
206 /* Set default shutdown parameters */
207 NewProcessData
->ShutdownLevel
= 0x280;
208 NewProcessData
->ShutdownFlags
= 0;
210 Request
->Status
= STATUS_SUCCESS
;
211 return(STATUS_SUCCESS
);
214 CSR_API(CsrTerminateProcess
)
216 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
217 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
);
219 if (ProcessData
== NULL
)
221 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
224 Request
->Status
= STATUS_SUCCESS
;
225 return STATUS_SUCCESS
;
228 CSR_API(CsrConnectProcess
)
230 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
231 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
233 Request
->Status
= STATUS_SUCCESS
;
235 return(STATUS_SUCCESS
);
238 CSR_API(CsrGetShutdownParameters
)
240 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
241 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
243 if (ProcessData
== NULL
)
245 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
248 Request
->Data
.GetShutdownParametersRequest
.Level
= ProcessData
->ShutdownLevel
;
249 Request
->Data
.GetShutdownParametersRequest
.Flags
= ProcessData
->ShutdownFlags
;
251 Request
->Status
= STATUS_SUCCESS
;
253 return(STATUS_SUCCESS
);
256 CSR_API(CsrSetShutdownParameters
)
258 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
259 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
261 if (ProcessData
== NULL
)
263 return(Request
->Status
= STATUS_INVALID_PARAMETER
);
266 ProcessData
->ShutdownLevel
= Request
->Data
.SetShutdownParametersRequest
.Level
;
267 ProcessData
->ShutdownFlags
= Request
->Data
.SetShutdownParametersRequest
.Flags
;
269 Request
->Status
= STATUS_SUCCESS
;
271 return(STATUS_SUCCESS
);
274 CSR_API(CsrGetInputHandle
)
276 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
277 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
279 if (ProcessData
== NULL
)
281 Request
->Data
.GetInputHandleRequest
.InputHandle
= INVALID_HANDLE_VALUE
;
282 Request
->Status
= STATUS_INVALID_PARAMETER
;
284 else if (ProcessData
->Console
)
286 Request
->Status
= CsrInsertObject(ProcessData
,
287 &Request
->Data
.GetInputHandleRequest
.InputHandle
,
288 (Object_t
*)ProcessData
->Console
);
292 Request
->Data
.GetInputHandleRequest
.InputHandle
= INVALID_HANDLE_VALUE
;
293 Request
->Status
= STATUS_SUCCESS
;
296 return Request
->Status
;
299 CSR_API(CsrGetOutputHandle
)
301 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
302 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
304 if (ProcessData
== NULL
)
306 Request
->Data
.GetOutputHandleRequest
.OutputHandle
= INVALID_HANDLE_VALUE
;
307 Request
->Status
= STATUS_INVALID_PARAMETER
;
309 else if (ProcessData
->Console
)
311 RtlEnterCriticalSection(&ProcessDataLock
);
312 Request
->Status
= CsrInsertObject(ProcessData
,
313 &Request
->Data
.GetOutputHandleRequest
.OutputHandle
,
314 &(ProcessData
->Console
->ActiveBuffer
->Header
));
315 RtlLeaveCriticalSection(&ProcessDataLock
);
319 Request
->Data
.GetOutputHandleRequest
.OutputHandle
= INVALID_HANDLE_VALUE
;
320 Request
->Status
= STATUS_SUCCESS
;
323 return Request
->Status
;
326 CSR_API(CsrCloseHandle
)
328 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
329 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
331 if (ProcessData
== NULL
)
333 Request
->Status
= STATUS_INVALID_PARAMETER
;
337 Request
->Status
= CsrReleaseObject(ProcessData
, Request
->Data
.CloseHandleRequest
.Handle
);
339 return Request
->Status
;
342 CSR_API(CsrVerifyHandle
)
344 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
345 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
347 Request
->Status
= CsrVerifyObject(ProcessData
, Request
->Data
.VerifyHandleRequest
.Handle
);
348 if (!NT_SUCCESS(Request
->Status
))
350 DPRINT("CsrVerifyObject failed, status=%x\n", Request
->Status
);
353 return Request
->Status
;
356 CSR_API(CsrDuplicateHandle
)
360 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
361 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
363 ProcessData
= CsrGetProcessData(Request
->Data
.DuplicateHandleRequest
.ProcessId
);
364 Request
->Status
= CsrGetObject(ProcessData
, Request
->Data
.DuplicateHandleRequest
.Handle
, &Object
);
365 if (! NT_SUCCESS(Request
->Status
))
367 DPRINT("CsrGetObject failed, status=%x\n", Request
->Status
);
371 Request
->Status
= CsrInsertObject(ProcessData
,
372 &Request
->Data
.DuplicateHandleRequest
.Handle
,
375 return Request
->Status
;
378 CSR_API(CsrGetInputWaitHandle
)
380 Request
->Header
.MessageSize
= sizeof(CSR_API_MESSAGE
);
381 Request
->Header
.DataSize
= sizeof(CSR_API_MESSAGE
) - LPC_MESSAGE_BASE_SIZE
;
383 if (ProcessData
== NULL
)
386 Request
->Data
.GetConsoleInputWaitHandle
.InputWaitHandle
= INVALID_HANDLE_VALUE
;
387 Request
->Status
= STATUS_INVALID_PARAMETER
;
391 Request
->Data
.GetConsoleInputWaitHandle
.InputWaitHandle
= ProcessData
->ConsoleEvent
;
392 Request
->Status
= STATUS_SUCCESS
;
394 return Request
->Status
;