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