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