reactos/reactos/subsys/csrss/api/process.c
Eric Kohl bb4e509794 Implemented [Get/Set]ProcessShutdownParameters().
svn path=/trunk/; revision=3645
2002-10-20 16:40:12 +00:00

261 lines
7 KiB
C

/* $Id: process.c,v 1.21 2002/10/20 16:40:12 ekohl Exp $
*
* reactos/subsys/csrss/api/process.c
*
* "\windows\ApiPort" port process management functions
*
* ReactOS Operating System
*/
/* INCLUDES ******************************************************************/
#include <ddk/ntddk.h>
#include <csrss/csrss.h>
#include <ntdll/rtl.h>
#include "api.h"
BOOL STDCALL W32kCleanupForProcess( INT Process );
#define LOCK RtlEnterCriticalSection(&ProcessDataLock)
#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
/* GLOBALS *******************************************************************/
static ULONG NrProcess;
static PCSRSS_PROCESS_DATA ProcessData[256];
extern CRITICAL_SECTION ActiveConsoleLock;
CRITICAL_SECTION ProcessDataLock;
/* FUNCTIONS *****************************************************************/
VOID STDCALL CsrInitProcessData(VOID)
{
/* ULONG i;
for (i=0; i<256; i++)
{
ProcessData[i] = NULL;
}
*/
RtlZeroMemory (ProcessData, sizeof ProcessData);
NrProcess = sizeof ProcessData / sizeof ProcessData[0];
RtlInitializeCriticalSection( &ProcessDataLock );
}
PCSRSS_PROCESS_DATA STDCALL CsrGetProcessData(ULONG ProcessId)
{
ULONG i;
LOCK;
for (i=0; i<NrProcess; i++)
{
if (ProcessData[i] &&
ProcessData[i]->ProcessId == ProcessId)
{
UNLOCK;
return(ProcessData[i]);
}
}
for (i=0; i<NrProcess; i++)
{
if (ProcessData[i] == NULL)
{
ProcessData[i] = RtlAllocateHeap(CsrssApiHeap,
HEAP_ZERO_MEMORY,
sizeof(CSRSS_PROCESS_DATA));
if (ProcessData[i] == NULL)
{
UNLOCK;
return(NULL);
}
ProcessData[i]->ProcessId = ProcessId;
UNLOCK;
return(ProcessData[i]);
}
}
// DbgPrint("CSR: CsrGetProcessData() failed\n");
UNLOCK;
return(NULL);
}
NTSTATUS STDCALL CsrFreeProcessData(ULONG Pid)
{
int i;
LOCK;
for( i = 0; i < NrProcess; i++ )
{
if( ProcessData[i] && ProcessData[i]->ProcessId == Pid )
{
//DbgPrint("CsrFreeProcessData pid: %d\n", Pid);
W32kCleanupForProcess( Pid ); //should check if win32k process
if( ProcessData[i]->HandleTable )
{
int c;
for( c = 0; c < ProcessData[i]->HandleTableSize; c++ )
if( ProcessData[i]->HandleTable[c] )
CsrReleaseObject( ProcessData[i], (HANDLE)((c + 1) << 2) );
RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i]->HandleTable );
}
if( ProcessData[i]->Console )
{
if( InterlockedDecrement( &(ProcessData[i]->Console->Header.ReferenceCount) ) == 0 )
CsrDeleteConsole( ProcessData[i]->Console );
}
RtlFreeHeap( CsrssApiHeap, 0, ProcessData[i] );
ProcessData[i] = 0;
UNLOCK;
return STATUS_SUCCESS;
}
}
UNLOCK;
return STATUS_INVALID_PARAMETER;
}
/**********************************************************************
* CSRSS API
*********************************************************************/
CSR_API(CsrCreateProcess)
{
PCSRSS_PROCESS_DATA NewProcessData;
NTSTATUS Status;
HANDLE Process;
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
NewProcessData = CsrGetProcessData(Request->Data.CreateProcessRequest.NewProcessId);
if (NewProcessData == NULL)
{
Reply->Status = STATUS_NO_MEMORY;
return(STATUS_NO_MEMORY);
}
/* Set default shutdown parameters */
NewProcessData->ShutdownLevel = 0x280;
NewProcessData->ShutdownFlags = 0;
if (Request->Data.CreateProcessRequest.Flags & DETACHED_PROCESS)
{
NewProcessData->Console = NULL;
}
else if (Request->Data.CreateProcessRequest.Flags & CREATE_NEW_CONSOLE)
{
PCSRSS_CONSOLE Console;
Console = RtlAllocateHeap(CsrssApiHeap,
HEAP_ZERO_MEMORY,
sizeof(CSRSS_CONSOLE));
Status = CsrInitConsole(Console);
if( !NT_SUCCESS( Status ) )
{
CsrFreeProcessData( NewProcessData->ProcessId );
Reply->Status = Status;
return Status;
}
NewProcessData->Console = Console;
Console->Header.ReferenceCount++;
}
else
{
NewProcessData->Console = ProcessData->Console;
InterlockedIncrement( &(ProcessData->Console->Header.ReferenceCount) );
}
if( NewProcessData->Console )
{
CLIENT_ID ClientId;
CsrInsertObject(NewProcessData,
&Reply->Data.CreateProcessReply.InputHandle,
(Object_t *)NewProcessData->Console);
RtlEnterCriticalSection( &ActiveConsoleLock );
CsrInsertObject( NewProcessData,
&Reply->Data.CreateProcessReply.OutputHandle,
&(NewProcessData->Console->ActiveBuffer->Header) );
RtlLeaveCriticalSection( &ActiveConsoleLock );
ClientId.UniqueProcess = (HANDLE)NewProcessData->ProcessId;
Status = NtOpenProcess( &Process, PROCESS_DUP_HANDLE, 0, &ClientId );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: NtOpenProcess() failed for handle duplication\n" );
InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
CsrFreeProcessData( NewProcessData->ProcessId );
Reply->Status = Status;
return Status;
}
Status = NtDuplicateObject( NtCurrentProcess(), NewProcessData->Console->ActiveEvent, Process, &NewProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
NtClose( Process );
InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
CsrFreeProcessData( NewProcessData->ProcessId );
Reply->Status = Status;
return Status;
}
NtClose( Process );
}
else Reply->Data.CreateProcessReply.OutputHandle = Reply->Data.CreateProcessReply.InputHandle = INVALID_HANDLE_VALUE;
return(STATUS_SUCCESS);
}
CSR_API(CsrTerminateProcess)
{
NTSTATUS Status;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY)
- sizeof(LPC_MESSAGE_HEADER);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY);
Status = CsrFreeProcessData(ProcessData->ProcessId);
Reply->Status = Status;
return Status;
}
CSR_API(CsrConnectProcess)
{
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Reply->Status = STATUS_SUCCESS;
return(STATUS_SUCCESS);
}
CSR_API(CsrGetShutdownParameters)
{
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
Reply->Data.GetShutdownParametersReply.Level = ProcessData->ShutdownLevel;
Reply->Data.GetShutdownParametersReply.Flags = ProcessData->ShutdownFlags;
Reply->Status = STATUS_SUCCESS;
return(STATUS_SUCCESS);
}
CSR_API(CsrSetShutdownParameters)
{
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
ProcessData->ShutdownLevel = Request->Data.SetShutdownParametersRequest.Level;
ProcessData->ShutdownFlags = Request->Data.SetShutdownParametersRequest.Flags;
Reply->Status = STATUS_SUCCESS;
return(STATUS_SUCCESS);
}
/* EOF */