mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
99af0f4db6
svn path=/trunk/; revision=7165
196 lines
5.9 KiB
C
196 lines
5.9 KiB
C
/* $Id: api.c,v 1.4 2003/12/21 20:11:46 ea Exp $
|
|
*
|
|
* PROJECT : ReactOS / POSIX+ Environment Subsystem Server
|
|
* FILE : reactos/subsys/psx/server/port/api.c
|
|
* DESCRIPTION: \POSIX+\ApiPort LPC port logic.
|
|
* DATE : 2001-04-04
|
|
* AUTHOR : Emanuele Aliberti <eal@users.sf.net>
|
|
*
|
|
* --------------------------------------------------------------------
|
|
*
|
|
* This software is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this software; see the file COPYING. If not, write
|
|
* to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
|
|
* MA 02139, USA.
|
|
*
|
|
* --------------------------------------------------------------------
|
|
*/
|
|
#include <psxss.h>
|
|
#include <psx/lpcproto.h>
|
|
#include "utils.h"
|
|
|
|
/**********************************************************************
|
|
* ProcessConnectionRequest/ PRIVATE
|
|
*
|
|
* DESCRIPTION
|
|
* This is called when a PSX process attaches to PSXDLL.DLL.
|
|
*/
|
|
PRIVATE NTSTATUS STDCALL
|
|
ProcessConnectionRequest (PLPC_MAX_MESSAGE pRequest)
|
|
{
|
|
PPSX_CONNECT_PORT_DATA pConnectData = (PPSX_CONNECT_PORT_DATA) & pRequest->Data;
|
|
NTSTATUS Status;
|
|
HANDLE hConnectedPort;
|
|
ULONG ulPortIdentifier;
|
|
|
|
debug_print (L"PSXSS: ->%s", __FUNCTION__);
|
|
/* Check if the caller is a process */
|
|
Status = PsxCheckConnectionRequest (
|
|
pConnectData,
|
|
PSX_CONNECTION_TYPE_PROCESS
|
|
);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
Status = NtAcceptConnectPort (
|
|
& hConnectedPort,
|
|
NULL,
|
|
& pRequest->Header,
|
|
FALSE, /* reject connection request */
|
|
NULL,
|
|
NULL
|
|
);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
debug_print(
|
|
L"PSXSS: %s: NtAcceptConnectPort failed with status=%08x",
|
|
__FUNCTION__,
|
|
Status
|
|
);
|
|
}
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
/* OK, accept the connection */
|
|
Status = NtAcceptConnectPort (
|
|
& hConnectedPort,
|
|
& ulPortIdentifier,
|
|
& pRequest->Header,
|
|
TRUE, /* accept connection request */
|
|
NULL,
|
|
NULL
|
|
);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
debug_print(L"PSXSS: %s: NtAcceptConnectPort failed with status=%08x", __FUNCTION__, Status);
|
|
return Status;
|
|
}
|
|
Status = PsxCreateProcess (pRequest,hConnectedPort,ulPortIdentifier);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
debug_print(L"PSXSS: %s: PsxCreateProcess failed with status=%08x", __FUNCTION__, Status);
|
|
return Status;
|
|
}
|
|
Status = NtCompleteConnectPort (hConnectedPort);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
debug_print(L"PSXSS: %s: NtCompleteConnectPort failed with status=%08x", __FUNCTION__, Status);
|
|
return Status;
|
|
}
|
|
debug_print (L"PSXSS: <-%s", __FUNCTION__);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
/**********************************************************************
|
|
* ProcessRequest/ PRIVATE
|
|
*
|
|
* DESCRIPTION
|
|
* This is the actual POSIX system calls dispatcher.
|
|
*/
|
|
PRIVATE NTSTATUS STDCALL
|
|
ProcessRequest (PPSX_MAX_MESSAGE pRequest)
|
|
{
|
|
debug_print (L"PSXSS: ->%s", __FUNCTION__);
|
|
|
|
if (pRequest->PsxHeader.Procedure < PSX_SYSCALL_APIPORT_COUNT)
|
|
{
|
|
pRequest->PsxHeader.Status =
|
|
SystemCall [pRequest->PsxHeader.Procedure] (pRequest);
|
|
}
|
|
else
|
|
{
|
|
pRequest->PsxHeader.Status = STATUS_INVALID_SYSTEM_SERVICE;
|
|
}
|
|
return STATUS_SUCCESS;
|
|
}
|
|
/**********************************************************************
|
|
* ApiPortListener/1
|
|
*
|
|
* DESCRIPTION
|
|
* The thread to process messages from the \POSIX+\ApiPort
|
|
* LPC port. Mostly used by PSXDLL.DLL.
|
|
*/
|
|
VOID STDCALL
|
|
ApiPortListener (PVOID pArg)
|
|
{
|
|
ULONG ulIndex = (ULONG) pArg;
|
|
NTSTATUS Status;
|
|
LPC_TYPE RequestType;
|
|
ULONG PortIdentifier;
|
|
PSX_MAX_MESSAGE Request;
|
|
PPSX_MAX_MESSAGE Reply = NULL;
|
|
BOOL NullReply = FALSE;
|
|
|
|
debug_print (L"PSXSS: ->%s pArg=%d", __FUNCTION__, ulIndex);
|
|
|
|
while (TRUE)
|
|
{
|
|
Reply = NULL;
|
|
NullReply = FALSE;
|
|
while (!NullReply)
|
|
{
|
|
Status = NtReplyWaitReceivePort (
|
|
Server.Port[ulIndex].hObject,
|
|
0,
|
|
(PLPC_MESSAGE) Reply,
|
|
(PLPC_MESSAGE) & Request
|
|
);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
break;
|
|
}
|
|
RequestType = PORT_MESSAGE_TYPE(Request);
|
|
switch (RequestType)
|
|
{
|
|
case LPC_CONNECTION_REQUEST:
|
|
ProcessConnectionRequest ((PLPC_MAX_MESSAGE) & Request);
|
|
NullReply = TRUE;
|
|
continue;
|
|
case LPC_CLIENT_DIED:
|
|
case LPC_PORT_CLOSED:
|
|
case LPC_DEBUG_EVENT:
|
|
case LPC_ERROR_EVENT:
|
|
case LPC_EXCEPTION:
|
|
NullReply = TRUE;
|
|
continue;
|
|
default:
|
|
if (RequestType != LPC_REQUEST)
|
|
{
|
|
NullReply = TRUE;
|
|
continue;
|
|
}
|
|
}
|
|
Reply = & Request;
|
|
Reply->PsxHeader.Status = ProcessRequest (& Request);
|
|
NullReply = FALSE;
|
|
}
|
|
if ((STATUS_INVALID_HANDLE == Status) ||
|
|
(STATUS_OBJECT_TYPE_MISMATCH == Status))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
#ifdef __PSXSS_ON_W32__
|
|
TerminateThread(GetCurrentThread(),Status);
|
|
#else
|
|
NtTerminateThread(NtCurrentThread(),Status);
|
|
#endif
|
|
}
|
|
/* EOF */
|