3 * reactos/subsys/csrss/api/process.c
5 * "\windows\ApiPort" port process management functions
7 * ReactOS Operating System
10 /* INCLUDES ******************************************************************/
12 #include <ddk/ntddk.h>
14 #include <csrss/csrss.h>
15 #include <ntdll/rtl.h>
21 BOOL STDCALL W32kCleanupForProcess( INT Process );
23 #define LOCK RtlEnterCriticalSection(&ProcessDataLock)
24 #define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
26 /* GLOBALS *******************************************************************/
28 static ULONG NrProcess;
29 static PCSRSS_PROCESS_DATA ProcessData[256];
30 extern CRITICAL_SECTION ActiveConsoleLock;
31 CRITICAL_SECTION ProcessDataLock;
33 /* FUNCTIONS *****************************************************************/
35 VOID STDCALL CsrInitProcessData(VOID)
37 RtlZeroMemory (ProcessData, sizeof ProcessData);
38 NrProcess = sizeof ProcessData / sizeof ProcessData[0];
39 RtlInitializeCriticalSection( &ProcessDataLock );
42 PCSRSS_PROCESS_DATA STDCALL CsrGetProcessData(ULONG ProcessId)
46 PCSRSS_PROCESS_DATA pProcessData;
48 hash = ProcessId % (sizeof(ProcessData) / sizeof(*ProcessData));
52 pProcessData = ProcessData[hash];
54 while (pProcessData && pProcessData->ProcessId != ProcessId)
56 pProcessData = pProcessData->next;
62 PCSRSS_PROCESS_DATA STDCALL CsrCreateProcessData(ULONG ProcessId)
66 PCSRSS_PROCESS_DATA pProcessData;
68 hash = ProcessId % (sizeof(ProcessData) / sizeof(*ProcessData));
72 pProcessData = ProcessData[hash];
74 while (pProcessData && pProcessData->ProcessId != ProcessId)
76 pProcessData = pProcessData->next;
78 if (pProcessData == NULL)
80 pProcessData = RtlAllocateHeap(CsrssApiHeap,
82 sizeof(CSRSS_PROCESS_DATA));
85 pProcessData->ProcessId = ProcessId;
86 pProcessData->next = ProcessData[hash];
87 ProcessData[hash] = pProcessData;
92 DPRINT("Process data for pid %d already exist\n", ProcessId);
95 if (pProcessData == NULL)
97 DbgPrint("CSR: CsrGetProcessData() failed\n");
102 NTSTATUS STDCALL CsrFreeProcessData(ULONG Pid)
106 PCSRSS_PROCESS_DATA pProcessData, pPrevProcessData = NULL;
108 hash = Pid % (sizeof(ProcessData) / sizeof(*ProcessData));
112 pProcessData = ProcessData[hash];
114 while (pProcessData && pProcessData->ProcessId != Pid)
116 pPrevProcessData = pProcessData;
117 pProcessData = pProcessData->next;
122 //DbgPrint("CsrFreeProcessData pid: %d\n", Pid);
123 W32kCleanupForProcess(Pid); //should check if win32k process
124 if (pProcessData->HandleTable)
126 for( c = 0; c < pProcessData->HandleTableSize; c++ )
128 if( pProcessData->HandleTable[c] )
130 CsrReleaseObject( pProcessData, (HANDLE)((c + 1) << 2) );
133 RtlFreeHeap( CsrssApiHeap, 0, pProcessData->HandleTable );
135 if( pProcessData->Console )
137 if( InterlockedDecrement( &(pProcessData->Console->Header.ReferenceCount) ) == 0 )
139 CsrDeleteConsole( pProcessData->Console );
142 if (pProcessData->CsrSectionViewBase)
144 NtUnmapViewOfSection(NtCurrentProcess(), pProcessData->CsrSectionViewBase);
146 if (pPrevProcessData)
148 pPrevProcessData->next = pProcessData->next;
152 ProcessData[hash] = pProcessData->next;
155 RtlFreeHeap( CsrssApiHeap, 0, pProcessData );
157 return STATUS_SUCCESS;
160 return STATUS_INVALID_PARAMETER;
164 /**********************************************************************
166 *********************************************************************/
168 CSR_API(CsrCreateProcess)
170 PCSRSS_PROCESS_DATA NewProcessData;
174 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
176 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
178 NewProcessData = CsrCreateProcessData(Request->Data.CreateProcessRequest.NewProcessId);
179 if (NewProcessData == NULL)
181 Reply->Status = STATUS_NO_MEMORY;
182 return(STATUS_NO_MEMORY);
185 /* Set default shutdown parameters */
186 NewProcessData->ShutdownLevel = 0x280;
187 NewProcessData->ShutdownFlags = 0;
189 if (Request->Data.CreateProcessRequest.Flags & DETACHED_PROCESS)
191 NewProcessData->Console = NULL;
193 else if (Request->Data.CreateProcessRequest.Flags & CREATE_NEW_CONSOLE)
195 PCSRSS_CONSOLE Console;
197 Console = RtlAllocateHeap(CsrssApiHeap,
199 sizeof(CSRSS_CONSOLE));
200 Status = CsrInitConsole(Console);
201 if( !NT_SUCCESS( Status ) )
203 CsrFreeProcessData( NewProcessData->ProcessId );
204 Reply->Status = Status;
207 NewProcessData->Console = Console;
208 Console->Header.ReferenceCount++;
212 NewProcessData->Console = ProcessData->Console;
213 InterlockedIncrement( &(ProcessData->Console->Header.ReferenceCount) );
216 if( NewProcessData->Console )
219 CsrInsertObject(NewProcessData,
220 &Reply->Data.CreateProcessReply.InputHandle,
221 (Object_t *)NewProcessData->Console);
222 RtlEnterCriticalSection( &ActiveConsoleLock );
223 CsrInsertObject( NewProcessData,
224 &Reply->Data.CreateProcessReply.OutputHandle,
225 &(NewProcessData->Console->ActiveBuffer->Header) );
227 RtlLeaveCriticalSection( &ActiveConsoleLock );
228 ClientId.UniqueProcess = (HANDLE)NewProcessData->ProcessId;
229 Status = NtOpenProcess( &Process, PROCESS_DUP_HANDLE, 0, &ClientId );
230 if( !NT_SUCCESS( Status ) )
232 DbgPrint( "CSR: NtOpenProcess() failed for handle duplication\n" );
233 InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
234 CsrFreeProcessData( NewProcessData->ProcessId );
235 Reply->Status = Status;
238 Status = NtDuplicateObject( NtCurrentProcess(), NewProcessData->Console->ActiveEvent, Process, &NewProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0 );
239 if( !NT_SUCCESS( Status ) )
241 DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
243 InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
244 CsrFreeProcessData( NewProcessData->ProcessId );
245 Reply->Status = Status;
250 else Reply->Data.CreateProcessReply.OutputHandle = Reply->Data.CreateProcessReply.InputHandle = INVALID_HANDLE_VALUE;
252 Reply->Status = STATUS_SUCCESS;
253 return(STATUS_SUCCESS);
256 CSR_API(CsrTerminateProcess)
260 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY)
261 - sizeof(LPC_MESSAGE);
262 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY);
264 if (ProcessData == NULL)
266 return(Reply->Status = STATUS_INVALID_PARAMETER);
269 Status = CsrFreeProcessData(ProcessData->ProcessId);
271 Reply->Status = Status;
275 CSR_API(CsrConnectProcess)
277 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
278 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
281 Reply->Status = STATUS_SUCCESS;
283 return(STATUS_SUCCESS);
286 CSR_API(CsrGetShutdownParameters)
288 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
289 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
292 if (ProcessData == NULL)
294 return(Reply->Status = STATUS_INVALID_PARAMETER);
297 Reply->Data.GetShutdownParametersReply.Level = ProcessData->ShutdownLevel;
298 Reply->Data.GetShutdownParametersReply.Flags = ProcessData->ShutdownFlags;
300 Reply->Status = STATUS_SUCCESS;
302 return(STATUS_SUCCESS);
305 CSR_API(CsrSetShutdownParameters)
307 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
308 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
311 if (ProcessData == NULL)
313 return(Reply->Status = STATUS_INVALID_PARAMETER);
316 ProcessData->ShutdownLevel = Request->Data.SetShutdownParametersRequest.Level;
317 ProcessData->ShutdownFlags = Request->Data.SetShutdownParametersRequest.Flags;
319 Reply->Status = STATUS_SUCCESS;
321 return(STATUS_SUCCESS);
324 CSR_API(CsrGetInputHandle)
326 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
327 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
329 if (ProcessData == NULL)
331 Reply->Data.GetInputHandleReply.InputHandle = INVALID_HANDLE_VALUE;
332 Reply->Status = STATUS_INVALID_PARAMETER;
334 else if (ProcessData->Console)
336 Reply->Status = CsrInsertObject(ProcessData,
337 &Reply->Data.GetInputHandleReply.InputHandle,
338 (Object_t *)ProcessData->Console);
342 Reply->Data.GetInputHandleReply.InputHandle = INVALID_HANDLE_VALUE;
343 Reply->Status = STATUS_SUCCESS;
346 return Reply->Status;
349 CSR_API(CsrGetOutputHandle)
351 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
352 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
354 if (ProcessData == NULL)
356 Reply->Data.GetOutputHandleReply.OutputHandle = INVALID_HANDLE_VALUE;
357 Reply->Status = STATUS_INVALID_PARAMETER;
359 else if (ProcessData->Console)
361 RtlEnterCriticalSection( &ActiveConsoleLock );
362 Reply->Status = CsrInsertObject(ProcessData,
363 &Reply->Data.GetOutputHandleReply.OutputHandle,
364 &(ProcessData->Console->ActiveBuffer->Header));
365 RtlLeaveCriticalSection( &ActiveConsoleLock );
369 Reply->Data.GetOutputHandleReply.OutputHandle = INVALID_HANDLE_VALUE;
370 Reply->Status = STATUS_SUCCESS;
373 return Reply->Status;
376 CSR_API(CsrCloseHandle)
378 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
379 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
381 if (ProcessData == NULL)
383 Reply->Status = STATUS_INVALID_PARAMETER;
387 Reply->Status = CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle);
389 return Reply->Status;
392 CSR_API(CsrVerifyHandle)
394 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
395 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
397 Reply->Status = CsrVerifyObject(ProcessData, Request->Data.VerifyHandleRequest.Handle);
398 if (!NT_SUCCESS(Reply->Status))
400 DPRINT("CsrVerifyObject failed, status=%x\n", Reply->Status);
403 return Reply->Status;
406 CSR_API(CsrDuplicateHandle)
410 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
411 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
413 ProcessData = CsrGetProcessData(Request->Data.DuplicateHandleRequest.ProcessId);
414 Reply->Status = CsrGetObject(ProcessData, Request->Data.DuplicateHandleRequest.Handle, &Object);
415 if (!NT_SUCCESS(Reply->Status))
417 DPRINT("CsrGetObject failed, status=%x\n", Reply->Status);
421 if (Object->Type == CSRSS_CONSOLE_MAGIC)
423 Reply->Status = CsrInsertObject(ProcessData,
424 &Reply->Data.DuplicateHandleReply.Handle,
425 (Object_t *)ProcessData->Console);
427 else if (Object->Type == CSRSS_SCREEN_BUFFER_MAGIC)
429 RtlEnterCriticalSection( &ActiveConsoleLock );
430 Reply->Status = CsrInsertObject(ProcessData,
431 &Reply->Data.DuplicateHandleReply.Handle,
432 &(ProcessData->Console->ActiveBuffer->Header));
433 RtlLeaveCriticalSection( &ActiveConsoleLock );
437 Reply->Status = STATUS_INVALID_PARAMETER;
440 return Reply->Status;