79e5f0cd7e60bfa84c7e82374e843a3fa8f70a81
[reactos.git] / reactos / subsys / csrss / api / process.c
1 /* $Id: process.c,v 1.12 2001/03/20 16:09:44 dwelch Exp $
2 *
3 * reactos/subsys/csrss/api/process.c
4 *
5 * "\windows\ApiPort" port process management functions
6 *
7 * ReactOS Operating System
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ddk/ntddk.h>
13
14 #include <csrss/csrss.h>
15 #include <ntdll/rtl.h>
16 #include "api.h"
17
18 /* GLOBALS *******************************************************************/
19
20 static ULONG NrProcess;
21 static PCSRSS_PROCESS_DATA ProcessData[256];
22 extern CRITICAL_SECTION ActiveConsoleLock;
23 CRITICAL_SECTION ProcessDataLock;
24
25 /* FUNCTIONS *****************************************************************/
26
27 VOID CsrInitProcessData(VOID)
28 {
29 ULONG i;
30
31 for (i=0; i<256; i++)
32 {
33 ProcessData[i] = NULL;
34 }
35 NrProcess = 256;
36 RtlInitializeCriticalSection( &ProcessDataLock );
37 }
38
39 PCSRSS_PROCESS_DATA CsrGetProcessData(ULONG ProcessId)
40 {
41 ULONG i;
42
43 RtlEnterCriticalSection( &ProcessDataLock );
44 for (i=0; i<NrProcess; i++)
45 {
46 if (ProcessData[i] &&
47 ProcessData[i]->ProcessId == ProcessId)
48 {
49 RtlLeaveCriticalSection( &ProcessDataLock );
50 return(ProcessData[i]);
51 }
52 }
53 for (i=0; i<NrProcess; i++)
54 {
55 if (ProcessData[i] == NULL)
56 {
57 ProcessData[i] = RtlAllocateHeap(CsrssApiHeap,
58 HEAP_ZERO_MEMORY,
59 sizeof(CSRSS_PROCESS_DATA));
60 if (ProcessData[i] == NULL)
61 {
62 RtlLeaveCriticalSection( &ProcessDataLock );
63 return(NULL);
64 }
65 ProcessData[i]->ProcessId = ProcessId;
66 RtlLeaveCriticalSection( &ProcessDataLock );
67 return(ProcessData[i]);
68 }
69 }
70 // DbgPrint("CSR: CsrGetProcessData() failed\n");
71 RtlLeaveCriticalSection(&ProcessDataLock);
72 return(NULL);
73 }
74
75 NTSTATUS CsrFreeProcessData(ULONG Pid)
76 {
77 int i;
78 RtlEnterCriticalSection( &ProcessDataLock );
79 for( i = 0; i < NrProcess; i++ )
80 {
81 if( ProcessData[i] && ProcessData[i]->ProcessId == Pid )
82 {
83 if( ProcessData[i]->HandleTable )
84 {
85 int c;
86 for( c = 0; c < ProcessData[i]->HandleTableSize; c++ )
87 if( ProcessData[i]->HandleTable[c] )
88 CsrReleaseObject( ProcessData[i], (HANDLE)((c + 1) << 2) );
89 RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i]->HandleTable );
90 }
91 if( ProcessData[i]->Console )
92 {
93 if( InterlockedDecrement( &(ProcessData[i]->Console->Header.ReferenceCount) ) == 0 )
94 CsrDeleteConsole( ProcessData[i]->Console );
95 }
96 RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i] );
97 ProcessData[i] = 0;
98 RtlLeaveCriticalSection( &ProcessDataLock );
99 return STATUS_SUCCESS;
100 }
101 }
102 RtlLeaveCriticalSection( &ProcessDataLock );
103 return STATUS_INVALID_PARAMETER;
104 }
105
106
107 NTSTATUS CsrCreateProcess (PCSRSS_PROCESS_DATA ProcessData,
108 PCSRSS_API_REQUEST Request,
109 PCSRSS_API_REPLY Reply)
110 {
111 PCSRSS_PROCESS_DATA NewProcessData;
112 NTSTATUS Status;
113 HANDLE Process;
114
115 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
116 sizeof(LPC_MESSAGE_HEADER);
117 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
118
119 NewProcessData = CsrGetProcessData(Request->Data.CreateProcessRequest.NewProcessId);
120 if (NewProcessData == NULL)
121 {
122 Reply->Status = STATUS_NO_MEMORY;
123 return(STATUS_NO_MEMORY);
124 }
125
126 if (Request->Data.CreateProcessRequest.Flags & DETACHED_PROCESS)
127 {
128 NewProcessData->Console = NULL;
129 }
130 else if (Request->Data.CreateProcessRequest.Flags & CREATE_NEW_CONSOLE)
131 {
132 PCSRSS_CONSOLE Console;
133
134 Console = RtlAllocateHeap(CsrssApiHeap,
135 HEAP_ZERO_MEMORY,
136 sizeof(CSRSS_CONSOLE));
137 Status = CsrInitConsole(Console);
138 if( !NT_SUCCESS( Status ) )
139 {
140 CsrFreeProcessData( NewProcessData->ProcessId );
141 Reply->Status = Status;
142 return Status;
143 }
144 NewProcessData->Console = Console;
145 Console->Header.ReferenceCount++;
146 }
147 else
148 {
149 NewProcessData->Console = ProcessData->Console;
150 InterlockedIncrement( &(ProcessData->Console->Header.ReferenceCount) );
151 }
152
153 if( NewProcessData->Console )
154 {
155 CLIENT_ID ClientId;
156 CsrInsertObject(NewProcessData,
157 &Reply->Data.CreateProcessReply.InputHandle,
158 (Object_t *)NewProcessData->Console);
159 RtlEnterCriticalSection( &ActiveConsoleLock );
160 CsrInsertObject( NewProcessData, &Reply->Data.CreateProcessReply.OutputHandle, &(NewProcessData->Console->ActiveBuffer->Header) );
161 RtlLeaveCriticalSection( &ActiveConsoleLock );
162 ClientId.UniqueProcess = (HANDLE)NewProcessData->ProcessId;
163 Status = NtOpenProcess( &Process, PROCESS_DUP_HANDLE, 0, &ClientId );
164 if( !NT_SUCCESS( Status ) )
165 {
166 DbgPrint( "CSR: NtOpenProcess() failed for handle duplication\n" );
167 InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
168 CsrFreeProcessData( NewProcessData->ProcessId );
169 Reply->Status = Status;
170 return Status;
171 }
172 Status = NtDuplicateObject( NtCurrentProcess(), &NewProcessData->Console->ActiveEvent, Process, &NewProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0 );
173 if( !NT_SUCCESS( Status ) )
174 {
175 DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
176 NtClose( Process );
177 InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
178 CsrFreeProcessData( NewProcessData->ProcessId );
179 Reply->Status = Status;
180 return Status;
181 }
182 NtClose( Process );
183 }
184 else Reply->Data.CreateProcessReply.OutputHandle = Reply->Data.CreateProcessReply.InputHandle = INVALID_HANDLE_VALUE;
185
186 return(STATUS_SUCCESS);
187 }
188
189 NTSTATUS CsrTerminateProcess(PCSRSS_PROCESS_DATA ProcessData,
190 PCSRSS_API_REQUEST LpcMessage,
191 PCSRSS_API_REPLY Reply)
192 {
193 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY)
194 - sizeof(LPC_MESSAGE_HEADER);
195 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY);
196
197 Reply->Status = STATUS_NOT_IMPLEMENTED;
198
199 return(STATUS_NOT_IMPLEMENTED);
200 }
201
202 NTSTATUS CsrConnectProcess(PCSRSS_PROCESS_DATA ProcessData,
203 PCSRSS_API_REQUEST Request,
204 PCSRSS_API_REPLY Reply)
205 {
206 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
207 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
208 sizeof(LPC_MESSAGE_HEADER);
209
210 Reply->Status = STATUS_SUCCESS;
211
212 return(STATUS_SUCCESS);
213 }
214
215 /* EOF */