2 * subsystems/win32/csrss/csrsrv/api/process.c
4 * "\windows\ApiPort" port process management functions
6 * ReactOS Operating System
9 /* INCLUDES ******************************************************************/
16 #define LOCK RtlEnterCriticalSection(&ProcessDataLock)
17 #define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
18 #define CsrAcquireProcessLock() LOCK
19 #define CsrReleaseProcessLock() UNLOCK
21 extern NTSTATUS
CallProcessInherit(PCSRSS_PROCESS_DATA
, PCSRSS_PROCESS_DATA
);
22 extern NTSTATUS
CallProcessDeleted(PCSRSS_PROCESS_DATA
);
24 /* GLOBALS *******************************************************************/
26 static ULONG NrProcess
;
27 PCSRSS_PROCESS_DATA ProcessData
[256];
28 RTL_CRITICAL_SECTION ProcessDataLock
;
29 extern PCSRSS_PROCESS_DATA CsrRootProcess
;
30 extern LIST_ENTRY CsrThreadHashTable
[256];
32 /* FUNCTIONS *****************************************************************/
34 VOID WINAPI
CsrInitProcessData(VOID
)
37 RtlZeroMemory (ProcessData
, sizeof ProcessData
);
38 NrProcess
= sizeof ProcessData
/ sizeof ProcessData
[0];
39 RtlInitializeCriticalSection( &ProcessDataLock
);
41 CsrRootProcess
= CsrCreateProcessData(NtCurrentTeb()->ClientId
.UniqueProcess
);
43 /* Initialize the Thread Hash List */
44 for (i
= 0; i
< 256; i
++) InitializeListHead(&CsrThreadHashTable
[i
]);
47 PCSRSS_PROCESS_DATA WINAPI
CsrGetProcessData(HANDLE ProcessId
)
50 PCSRSS_PROCESS_DATA pProcessData
;
52 hash
= ((ULONG_PTR
)ProcessId
>> 2) % (sizeof(ProcessData
) / sizeof(*ProcessData
));
56 pProcessData
= ProcessData
[hash
];
58 while (pProcessData
&& pProcessData
->ProcessId
!= ProcessId
)
60 pProcessData
= pProcessData
->next
;
66 PCSRSS_PROCESS_DATA WINAPI
CsrCreateProcessData(HANDLE ProcessId
)
69 PCSRSS_PROCESS_DATA pProcessData
;
70 OBJECT_ATTRIBUTES ObjectAttributes
;
74 hash
= ((ULONG_PTR
)ProcessId
>> 2) % (sizeof(ProcessData
) / sizeof(*ProcessData
));
78 pProcessData
= ProcessData
[hash
];
80 while (pProcessData
&& pProcessData
->ProcessId
!= ProcessId
)
82 pProcessData
= pProcessData
->next
;
84 if (pProcessData
== NULL
)
86 pProcessData
= RtlAllocateHeap(CsrssApiHeap
,
88 sizeof(CSRSS_PROCESS_DATA
));
91 pProcessData
->ProcessId
= ProcessId
;
92 pProcessData
->next
= ProcessData
[hash
];
93 ProcessData
[hash
] = pProcessData
;
95 ClientId
.UniqueThread
= NULL
;
96 ClientId
.UniqueProcess
= pProcessData
->ProcessId
;
97 InitializeObjectAttributes(&ObjectAttributes
,
103 /* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
104 Status
= NtOpenProcess(&pProcessData
->Process
,
108 DPRINT1("CSR Process: %p Handle: %p\n", pProcessData
, pProcessData
->Process
);
109 if (!NT_SUCCESS(Status
))
111 ProcessData
[hash
] = pProcessData
->next
;
112 RtlFreeHeap(CsrssApiHeap
, 0, pProcessData
);
117 RtlInitializeCriticalSection(&pProcessData
->HandleTableLock
);
123 DPRINT1("Process data for pid %d already exist\n", ProcessId
);
126 if (pProcessData
== NULL
)
128 DPRINT1("CsrCreateProcessData() failed\n");
132 pProcessData
->Terminated
= FALSE
;
134 /* Set default shutdown parameters */
135 pProcessData
->ShutdownLevel
= 0x280;
136 pProcessData
->ShutdownFlags
= 0;
139 pProcessData
->ThreadCount
= 0;
140 InitializeListHead(&pProcessData
->ThreadList
);
144 NTSTATUS WINAPI
CsrFreeProcessData(HANDLE Pid
)
147 PCSRSS_PROCESS_DATA pProcessData
, *pPrevLink
;
149 PLIST_ENTRY NextEntry
;
152 hash
= ((ULONG_PTR
)Pid
>> 2) % (sizeof(ProcessData
) / sizeof(*ProcessData
));
153 pPrevLink
= &ProcessData
[hash
];
157 while ((pProcessData
= *pPrevLink
) && pProcessData
->ProcessId
!= Pid
)
159 pPrevLink
= &pProcessData
->next
;
164 DPRINT("CsrFreeProcessData pid: %d\n", Pid
);
165 Process
= pProcessData
->Process
;
166 CallProcessDeleted(pProcessData
);
168 /* Dereference all process threads */
169 NextEntry
= pProcessData
->ThreadList
.Flink
;
170 while (NextEntry
!= &pProcessData
->ThreadList
)
172 Thread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, Link
);
173 NextEntry
= NextEntry
->Flink
;
175 CsrThreadRefcountZero(Thread
);
178 if (pProcessData
->CsrSectionViewBase
)
180 NtUnmapViewOfSection(NtCurrentProcess(), pProcessData
->CsrSectionViewBase
);
183 if (pProcessData
->ServerCommunicationPort
)
185 NtClose(pProcessData
->ServerCommunicationPort
);
188 *pPrevLink
= pProcessData
->next
;
190 RtlFreeHeap(CsrssApiHeap
, 0, pProcessData
);
196 return STATUS_SUCCESS
;
200 return STATUS_INVALID_PARAMETER
;
203 /**********************************************************************
205 *********************************************************************/
207 CSR_API(CsrCreateProcess
)
209 PCSRSS_PROCESS_DATA NewProcessData
;
212 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
213 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
215 NewProcessData
= CsrCreateProcessData(Request
->Data
.CreateProcessRequest
.NewProcessId
);
216 if (NewProcessData
== NULL
)
218 return(STATUS_NO_MEMORY
);
221 if (!(Request
->Data
.CreateProcessRequest
.Flags
& (CREATE_NEW_CONSOLE
|DETACHED_PROCESS
)))
223 NewProcessData
->ParentConsole
= ProcessData
->Console
;
224 NewProcessData
->bInheritHandles
= Request
->Data
.CreateProcessRequest
.bInheritHandles
;
225 if (Request
->Data
.CreateProcessRequest
.bInheritHandles
)
227 Status
= CallProcessInherit(ProcessData
, NewProcessData
);
231 if (Request
->Data
.CreateProcessRequest
.Flags
& CREATE_NEW_PROCESS_GROUP
)
233 NewProcessData
->ProcessGroup
= (DWORD
)(ULONG_PTR
)NewProcessData
->ProcessId
;
237 NewProcessData
->ProcessGroup
= ProcessData
->ProcessGroup
;
240 return(STATUS_SUCCESS
);
243 CSR_API(CsrSrvCreateThread
)
245 PCSR_THREAD CurrentThread
;
248 PCSRSS_PROCESS_DATA CsrProcess
;
250 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
251 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
253 CurrentThread
= NtCurrentTeb()->CsrClientThread
;
254 CsrProcess
= CurrentThread
->Process
;
255 // DPRINT1("Current thread: %p %p\n", CurrentThread, CsrProcess);
256 // DPRINT1("Request CID: %lx %lx %lx\n",
257 // CsrProcess->ProcessId,
258 // NtCurrentTeb()->ClientId.UniqueProcess,
259 // Request->Data.CreateThreadRequest.ClientId.UniqueProcess);
261 if (CsrProcess
->ProcessId
!= Request
->Data
.CreateThreadRequest
.ClientId
.UniqueProcess
)
263 if (Request
->Data
.CreateThreadRequest
.ClientId
.UniqueProcess
== NtCurrentTeb()->ClientId
.UniqueProcess
)
265 return STATUS_SUCCESS
;
268 Status
= CsrLockProcessByClientId(Request
->Data
.CreateThreadRequest
.ClientId
.UniqueProcess
,
270 // DPRINT1("Found matching process: %p\n", CsrProcess);
271 if (!NT_SUCCESS(Status
)) return Status
;
274 // DPRINT1("PIDs: %lx %lx\n", CurrentThread->Process->ProcessId, CsrProcess->ProcessId);
275 // DPRINT1("Thread handle is: %lx Process Handle is: %lx %lx\n",
276 // Request->Data.CreateThreadRequest.ThreadHandle,
277 // CurrentThread->Process->Process,
278 // CsrProcess->Process);
279 Status
= NtDuplicateObject(CsrProcess
->Process
,
280 Request
->Data
.CreateThreadRequest
.ThreadHandle
,
285 DUPLICATE_SAME_ACCESS
);
286 //DPRINT1("Duplicate status: %lx\n", Status);
287 if (!NT_SUCCESS(Status
))
289 Status
= NtDuplicateObject(CurrentThread
->Process
->Process
,
290 Request
->Data
.CreateThreadRequest
.ThreadHandle
,
295 DUPLICATE_SAME_ACCESS
);
296 // DPRINT1("Duplicate status: %lx\n", Status);
299 Status
= STATUS_SUCCESS
; // hack
300 if (NT_SUCCESS(Status
))
302 Status
= CsrCreateThread(CsrProcess
,
304 &Request
->Data
.CreateThreadRequest
.ClientId
);
305 // DPRINT1("Create status: %lx\n", Status);
308 if (CsrProcess
!= CurrentThread
->Process
) CsrReleaseProcessLock();
313 CSR_API(CsrTerminateProcess
)
315 PLIST_ENTRY NextEntry
;
317 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
318 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
320 NextEntry
= ProcessData
->ThreadList
.Flink
;
321 while (NextEntry
!= &ProcessData
->ThreadList
)
323 Thread
= CONTAINING_RECORD(NextEntry
, CSR_THREAD
, Link
);
324 NextEntry
= NextEntry
->Flink
;
326 CsrThreadRefcountZero(Thread
);
331 ProcessData
->Terminated
= TRUE
;
332 return STATUS_SUCCESS
;
335 CSR_API(CsrConnectProcess
)
337 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
338 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
340 return(STATUS_SUCCESS
);
343 CSR_API(CsrGetShutdownParameters
)
345 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
346 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
348 Request
->Data
.GetShutdownParametersRequest
.Level
= ProcessData
->ShutdownLevel
;
349 Request
->Data
.GetShutdownParametersRequest
.Flags
= ProcessData
->ShutdownFlags
;
351 return(STATUS_SUCCESS
);
354 CSR_API(CsrSetShutdownParameters
)
356 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
357 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
359 ProcessData
->ShutdownLevel
= Request
->Data
.SetShutdownParametersRequest
.Level
;
360 ProcessData
->ShutdownFlags
= Request
->Data
.SetShutdownParametersRequest
.Flags
;
362 return(STATUS_SUCCESS
);