mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 18:24:02 +00:00
261 lines
7 KiB
C
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 */
|