From bb24d01a481970e4327cc9817a4243cf958af764 Mon Sep 17 00:00:00 2001 From: Emanuele Aliberti Date: Wed, 10 Apr 2002 21:30:22 +0000 Subject: [PATCH] PSX: early code for the PSXSS server program. Currently it is a W32 console application, therefore it is not a proper subsystem, but it will be converted to native as soon as it begins working. It probably does NOT work under ROS. I tested it under NT 4.0 SP 6a. To see what it creates in the system name sapce, run WinObj, and HandleEx. If you run csrterm.exe, it tries to connect to psxss.exe, but then dies because the API to tell psxss to create a PSX process it not implemented yet. PSXDLL.DLL will connect to \POSIX+\ApiPort (initial code in psx/lib/psxdll/misc/init.c is mute). svn path=/trunk/; revision=2841 --- posix/Makefile | 30 ++++ posix/include/psx/lpcproto.h | 14 +- posix/lib/crt0w32.c | 6 +- posix/lib/psxdll/misc/init.c | 40 ++++- posix/server/Makefile | 51 ++++++ posix/server/call/_exit.c | 40 +++++ posix/server/call/null.c | 39 +++++ posix/server/include/psxss.h | 155 +++++++++++++++++ posix/server/misc/init.c | 320 +++++++++++++++++++++++++++++++++++ posix/server/misc/main.c | 89 ++++++++++ posix/server/misc/print.c | 18 ++ posix/server/misc/psxss.rc | 39 +++++ posix/server/ob/process.c | 56 ++++++ posix/server/ob/session.c | 307 +++++++++++++++++++++++++++++++++ posix/server/ob/terminal.c | 56 ++++++ posix/server/port/api.c | 195 +++++++++++++++++++++ posix/server/port/sbapi.c | 76 +++++++++ posix/server/port/session.c | 194 +++++++++++++++++++++ posix/server/port/utils.c | 67 ++++++++ posix/server/port/utils.h | 4 + 20 files changed, 1787 insertions(+), 9 deletions(-) create mode 100644 posix/Makefile create mode 100644 posix/server/Makefile create mode 100644 posix/server/call/_exit.c create mode 100644 posix/server/call/null.c create mode 100644 posix/server/include/psxss.h create mode 100644 posix/server/misc/init.c create mode 100644 posix/server/misc/main.c create mode 100644 posix/server/misc/print.c create mode 100644 posix/server/misc/psxss.rc create mode 100644 posix/server/ob/process.c create mode 100644 posix/server/ob/session.c create mode 100644 posix/server/ob/terminal.c create mode 100644 posix/server/port/api.c create mode 100644 posix/server/port/sbapi.c create mode 100644 posix/server/port/session.c create mode 100644 posix/server/port/utils.c create mode 100644 posix/server/port/utils.h diff --git a/posix/Makefile b/posix/Makefile new file mode 100644 index 00000000000..3458d47d218 --- /dev/null +++ b/posix/Makefile @@ -0,0 +1,30 @@ +# $Id: Makefile,v 1.1 2002/04/10 21:30:20 ea Exp $ +# +# ReactOS POSIX+ Personality +# +PATH_TO_TOP=../.. + +CFLAGS=-Iinclude + +all: lib/crt0w32.o + make -C tools + make -C server + make -C lib/psxdll + make -C lib/psxx + make -C apps/baresh + make -C apps/csrterm + +lib/crt0w32.o: lib/crt0w32.c + +clean: + make -C tools clean + make -C server clean + make -C lib/psxdll clean + make -C lib/psxx clean + make -C apps/baresh clean + make -C apps/csrterm clean + - $(RM) lib/crt0w32.o + +include $(PATH_TO_TOP)/rules.mak + +# EOF diff --git a/posix/include/psx/lpcproto.h b/posix/include/psx/lpcproto.h index 791174a5eec..1e916b48809 100644 --- a/posix/include/psx/lpcproto.h +++ b/posix/include/psx/lpcproto.h @@ -1,4 +1,4 @@ -/* $Id: lpcproto.h,v 1.2 2002/04/07 13:56:16 ea Exp $ +/* $Id: lpcproto.h,v 1.3 2002/04/10 21:30:20 ea Exp $ * * ReactOS POSIX+ Environment Subsystem * LPC protocol spoken by PSXSS.EXE, PSXDLL.DLL, CSRTERM.EXE. @@ -30,7 +30,8 @@ typedef enum { PSX_CONNECTION_TYPE_PROCESS, - PSX_CONNECTION_TYPE_TERMINAL + PSX_CONNECTION_TYPE_TERMINAL, + PSX_CONNECTION_TYPE_SERVER } PSX_CONNECTION_TYPE; typedef struct _PSX_CONNECT_PORT_DATA @@ -38,7 +39,7 @@ typedef struct _PSX_CONNECT_PORT_DATA PSX_CONNECTION_TYPE ConnectionType; /* IN OUT */ ULONG Version; /* IN OUT */ ULONG PortIdentifier; /* OUT */ -} PSX_CONNECT_PORT_DATA; +} PSX_CONNECT_PORT_DATA, * PPSX_CONNECT_PORT_DATA; /* LPC message subsystem-specific header */ @@ -64,17 +65,20 @@ typedef struct _PSX_MAX_MESSAGE /* \POSIX+\SessionPort API */ +#define PSX_TERMINAL_SECTION_SIZE 65536L +#define PSX_TERMINAL_SECTION_OFFSET 8192L + typedef enum { PSX_TERMINAL_INTERRUPT, PSX_TERMINAL_SESSION_STATUS_REQUEST } PSX_TERMINAL_API; -typedef struct _PSX_TERMINAL_READ +typedef struct _PSX_TERMINAL_IO { LPC_MESSAGE_HEADER Header; PSX_MESSAGE_HEADER PsxHeader; ULONG Size; - CHAR Buffer [80]; /* FIXME! */ + ULONG Offset; } PSX_TERMINAL_READ, * PPSX_TERMINAL_READ; /* System I/O (system calls) */ diff --git a/posix/lib/crt0w32.c b/posix/lib/crt0w32.c index 0d9cc07fddb..cf80622f178 100644 --- a/posix/lib/crt0w32.c +++ b/posix/lib/crt0w32.c @@ -1,10 +1,10 @@ -/* $Id: crt0w32.c,v 1.1 2002/01/20 21:24:49 ea Exp $ +/* $Id: crt0w32.c,v 1.2 2002/04/10 21:30:21 ea Exp $ * * PROJECT : ReactOS / POSIX+ personality - * FILE : subsys/psx/lib/cr0w32.c + * FILE : subsys/psx/lib/crt0w32.c * DESCRIPTION: startup code for POSIX+ applications. * DATE : 2002-01-18 - * AUTHOR : Emanuele Aliberti + * AUTHOR : Emanuele Aliberti */ extern void __stdcall __PdxInitializeData(int*,char***); diff --git a/posix/lib/psxdll/misc/init.c b/posix/lib/psxdll/misc/init.c index 9ed5ba8370d..be317626033 100644 --- a/posix/lib/psxdll/misc/init.c +++ b/posix/lib/psxdll/misc/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 2002/02/24 22:14:05 ea Exp $ +/* $Id: init.c,v 1.2 2002/04/10 21:30:21 ea Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS POSIX+ Subsystem @@ -10,10 +10,12 @@ */ #define NTOS_MODE_USER #include +#include /* DLL GLOBALS */ int * errno = NULL; char *** _environ = NULL; +HANDLE ApiPort = INVALID_HANDLE_VALUE; /* * Called by startup code in crt0.o, where real * errno and _environ are actually defined. @@ -23,5 +25,41 @@ VOID STDCALL __PdxInitializeData (int * errno_arg, char *** environ_arg) errno = errno_arg; _environ = environ_arg; } +/* + * Called by DLL's entry point when reason==PROCESS_ATTACH. + */ +NTATATUS STDCALL PsxConnectApiPort (VOID) +{ + UNICODE_STRING usApiPortName; + LPWSTR wsApiPortName = L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_API_PORT_NAME; + SECURITY_QUALITY_OF_SERVICE Sqos; + ULONG MaxMessageSize = 0; + NTSTATUS Status; + PSX_CONNECT_PORT_DATA ConnectData; + ULONG ConnectDataLength = sizeof ConnectData; + + RtlInitUnicodeString (& usApiPortName, wsApiPortName); + RtlZeroMemory (Sqos, sizeof Sqos); + ConnectData.ConnectionType = PSX_CONNECTION_TYPE_PROCESS; + ConnectData.Version = PSX_LPC_PROTOCOL_VERSION; + ConnectData.PortIdentifier = 0; + Status = NtConnectPort ( + & ApiPort, + & usApiPortName, + & Sqos, + NULL, + NULL, + & MaxMessageSize, + & ConnectData, + & ConnectDataLength + ); + if (!NT_SUCCESS(Status)) + { + /* TODO: emit a diagnostic message */ + return Status; + } + /* TODO: save returned data */ + return STATUS_SUCCESS; +} /* EOF */ diff --git a/posix/server/Makefile b/posix/server/Makefile new file mode 100644 index 00000000000..23aa03a0ad1 --- /dev/null +++ b/posix/server/Makefile @@ -0,0 +1,51 @@ +# $Id: Makefile,v 1.1 2002/04/10 21:30:21 ea Exp $ +# +# ReactOS POSIX+ Environment Subsystem +# +PATH_TO_TOP=../../.. + +TARGET_TYPE = program + +TARGET_PATH = misc + +TARGET_NAME = psxss + +TARGET_APPTYPE = console + +TARGET_SDKLIBS = ntdll.a kernel32.a + +TARGET_CFLAGS=-Iinclude -I../include -D__PSXSS_ON_W32__ + +PSXSS_MISC_OBJECTS = \ + misc/main.o \ + misc/init.o \ + misc/print.o + +PSXSS_OB_OBJECTS = \ + ob/process.o \ + ob/session.o \ + ob/terminal.o + +PSXSS_PORT_OBJECTS = \ + port/api.o \ + port/sbapi.o \ + port/session.o \ + port/utils.o + +PSXSS_CALL_OBJECTS = \ + call/null.o \ + call/_exit.o \ + call/stubs.o \ + call/syscall.o + +TARGET_OBJECTS=\ + $(PSXSS_MISC_OBJECTS) \ + $(PSXSS_OB_OBJECTS) \ + $(PSXSS_PORT_OBJECTS) \ + $(PSXSS_CALL_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/posix/server/call/_exit.c b/posix/server/call/_exit.c new file mode 100644 index 00000000000..40b1e103284 --- /dev/null +++ b/posix/server/call/_exit.c @@ -0,0 +1,40 @@ +/* $Id: _exit.c,v 1.1 2002/04/10 21:30:21 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/call/_exit.c + * DESCRIPTION: System call _exit(). + * DATE : 2002-04-05 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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. + * + * -------------------------------------------------------------------- + */ +#define NTOS_MODE_USER +#include +#include +#include +#include + +NTSTATUS STDCALL syscall__exit (PPSX_MAX_MESSAGE Msg) +{ + Msg->PsxHeader.Status = STATUS_SUCCESS; + /* TODO */ + return STATUS_SUCCESS; +} +/* EOF */ diff --git a/posix/server/call/null.c b/posix/server/call/null.c new file mode 100644 index 00000000000..90d8fcc0dc1 --- /dev/null +++ b/posix/server/call/null.c @@ -0,0 +1,39 @@ +/* $Id: null.c,v 1.1 2002/04/10 21:30:21 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/call/null.c + * DESCRIPTION: Void system call. + * DATE : 2002-04-05 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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. + * + * -------------------------------------------------------------------- + */ +#define NTOS_MODE_USER +#include +#include +#include +#include + +NTSTATUS STDCALL syscall_null (PPSX_MAX_MESSAGE Msg) +{ + Msg->PsxHeader.Status = STATUS_SUCCESS; + return STATUS_SUCCESS; +} +/* EOF */ diff --git a/posix/server/include/psxss.h b/posix/server/include/psxss.h new file mode 100644 index 00000000000..815334dc925 --- /dev/null +++ b/posix/server/include/psxss.h @@ -0,0 +1,155 @@ +/* $Id: psxss.h,v 1.1 2002/04/10 21:30:21 ea Exp $ */ +#ifndef _PSX_PSXSS_H +#define _PSX_PSXSS_H + +#define NTOS_MODE_USER +#include +#include +#include + +#ifdef __PSXSS_ON_W32__ +#include +#endif + +#define NAME_BUFFER_SIZE 64 + +/* PSXSS GLOBAL DATA */ + +typedef struct _SERVER_DIRECTORY +{ + HANDLE hObject; + LPWSTR wsName; + UNICODE_STRING usName; + +} SERVER_DIRECTORY; + +#define PSXSS_THREADS_PER_PORT 2 + +typedef struct _SERVER_PORT +{ + HANDLE hObject; + LPWSTR wsName; + UNICODE_STRING usName; + PTHREAD_START_ROUTINE EntryPoint; + struct { + HANDLE hObject; + DWORD Id; + } ThreadInfo [PSXSS_THREADS_PER_PORT]; + +} SERVER_PORT, * PSERVER_PORT; + +#define SERVER_DIRECTORY_COUNT 3 +#define SERVER_PORT_COUNT 3 + +typedef struct _SERVER +{ + HANDLE Heap; + SERVER_DIRECTORY Directory [SERVER_DIRECTORY_COUNT]; + SERVER_PORT Port [SERVER_PORT_COUNT]; + +} SERVER; + +#define PSX_PORT_API 0 +#define PSX_PORT_SBAPI 1 +#define PSX_PORT_SESSION 2 + +#define PSX_DIRECTORY_POSIX 0 +#define PSX_DIRECTORY_SESSIONS 1 +#define PSX_DIRECTORY_SYSTEM 2 + +extern SERVER Server; /* server/misc/init.c */ + +/* System call type */ +typedef NTSTATUS (STDCALL *PSX_SYSTEM_CALL)(PPSX_MAX_MESSAGE); + +/* System calls table */ + +extern PSX_SYSTEM_CALL SystemCall []; /* server/call/syscall.c */ + +/* Listener's Threads */ +VOID STDCALL ApiPortListener (PVOID); +VOID STDCALL SbApiPortListener (PVOID); +VOID STDCALL SessionPortListener (PVOID); + +/* TERMINAL OBJECT */ + +typedef struct _PSX_TERMINAL +{ + DWORD Id; + /* TODO */ +} PSX_TERMINAL, * PPSX_TERMINAL; + +/* PROCESS OBJECT */ + +typedef enum +{ + PROCESS_STATUS_INITIALIZATION, + PROCESS_STATUS_READY, + PROCESS_STATUS_WAITING, + PROCESS_STATUS_DEAD, + PROCESS_STATUS_ZOMBIE + +} PROCESS_STATUS; + +typedef DWORD PSX_SECURITY; /* TODO */ + +struct _PSX_SESSION; + +typedef struct _PSX_PROCESS +{ + INT Id; /* pid */ + HANDLE hProcess; /* hProcess */ + PROCESS_STATUS Status; + struct _PSX_PROCESS * Parent; + struct _PSX_SESSION * Session; + PPSX_TERMINAL ControlTty; + PSX_SECURITY Security; + +} PSX_PROCESS, * PPSX_PROCESS; + +/* SESSION OBJECT */ + +typedef enum +{ + SESSION_STATUS_INITIALIZATION, + SESSION_STATUS_READY, + SESSION_STATUS_SHUTDOWN, + SESSION_STATUS_ERROR + +} SESSION_STATUS; + +typedef struct _PSX_SESSION +{ + DWORD Id; + ULONG ReferenceCount; + SESSION_STATUS Status; + HANDLE Heap; + struct { + HANDLE hPort; + ULONG ulPortIdentifier; + } SessionChannel; + struct { + ULONG Id; /* csrterm pid */ + HANDLE hPort; /* LPC port owned by csrterm: \POSIX+\Sessions\P{Id} */ + struct { + HANDLE Handle; /* Section owned by csrterm: \POSIX+\Sessions\D{Id} */ + PVOID BaseAddress; + ULONG ViewSize; + } Section; + } TerminalChannel; + PPSX_PROCESS Leader; + CRITICAL_SECTION Lock; + struct _PSX_SESSION * Previous; + struct _PSX_SESSION * Next; + +} PSX_SESSION, * PPSX_SESSION; + +/* prototypes */ + +VOID STDCALL debug_print (LPWSTR Template, ...); +NTSTATUS STDCALL PsxInitializeSessions (VOID); /* ob/session.c */ +NTSTATUS STDCALL PsxCreateSession (PLPC_MAX_MESSAGE,HANDLE,ULONG); +NTSTATUS STDCALL PsxInitializeProcesses (VOID); /* ob/process.c */ +NTSTATUS STDCALL PsxCreateProcess (PLPC_MAX_MESSAGE,HANDLE,ULONG); + +#endif /* ndef _PSX_PSXSS_H */ diff --git a/posix/server/misc/init.c b/posix/server/misc/init.c new file mode 100644 index 00000000000..a7b3072539e --- /dev/null +++ b/posix/server/misc/init.c @@ -0,0 +1,320 @@ +/* $Id: init.c,v 1.1 2002/04/10 21:30:21 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/srv/init.c + * DESCRIPTION: POSIX+ server initialization. + * DATE : 2001-05-05 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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 +#include + +#ifdef __PSXSS_ON_W32__ +#include +#endif + +/*** GLOBALS *********************************************************/ + +SERVER Server = +{ + /* .Heap */ + INVALID_HANDLE_VALUE, + /* .Directory */ + { + { INVALID_HANDLE_VALUE, + L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME, + {0,0,NULL} + }, + { INVALID_HANDLE_VALUE, + L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SESSION_DIRECTORY_NAME, + {0,0,NULL} + }, + { INVALID_HANDLE_VALUE, + L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SYSTEM_DIRECTORY_NAME, + {0,0,NULL} + }, + }, + /* .Port */ + { + { INVALID_HANDLE_VALUE, + L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_API_PORT_NAME, + {0,0,NULL}, + ApiPortListener + }, + { INVALID_HANDLE_VALUE, + L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SBAPI_PORT_NAME, + {0,0,NULL}, + SbApiPortListener + }, + { INVALID_HANDLE_VALUE, + L"\\"PSX_NS_SUBSYSTEM_DIRECTORY_NAME"\\"PSX_NS_SESSIONAPI_PORT_NAME, + {0,0,NULL}, + SessionPortListener + } + } +}; + +/*** FUNCTIONS *******************************************************/ + +/********************************************************************** + * PdxInitializeHeap/0 PRIVATE + * + * DESCRIPTION + * Initialize the PSX server process' heap. + */ +PRIVATE HANDLE STDCALL +PdxInitializeHeap (VOID) +{ + return Server.Heap = (HANDLE)NtCurrentPeb()->ProcessHeap; +} +/********************************************************************** + * PdxCreateDirectory/1 PRIVATE + * + * DESCRIPTION + * Create a directory in the system name space. + */ +PRIVATE NTSTATUS STDCALL +PdxCreateDirectory ( + IN ULONG ulIndex + ) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + + RtlCreateUnicodeString ( + & Server.Directory[ulIndex].usName, + Server.Directory[ulIndex].wsName + ); + InitializeObjectAttributes ( + & ObjectAttributes, + & Server.Directory[ulIndex].usName, + 0, + NULL, + NULL + ); + Status = NtCreateDirectoryObject( + & Server.Directory[ulIndex].hObject, + DIRECTORY_ALL_ACCESS, + & ObjectAttributes + ); + if (!NT_SUCCESS(Status)) + { + debug_print( + L"PSXSS: %s directory creation failed (Status = %08x)", + Server.Directory[ulIndex].wsName, + Status + ); + + } + return Status; +} +/********************************************************************** + * PdxInitializeDirectories/0 PRIVATE + * + * DESCRIPTION + * Create the directories used by the POSIX+ subsystem + * components in the system name space. + */ +PRIVATE NTSTATUS STDCALL +PdxInitializeDirectories (VOID) +{ + NTSTATUS Status; + ULONG ulIndex; + + for ( ulIndex = 0; + (ulIndex < (sizeof Server.Directory / sizeof Server.Directory[0])); + ulIndex ++) + { + Status = PdxCreateDirectory (ulIndex); + if (!NT_SUCCESS(Status)) return Status; + } + return STATUS_SUCCESS; +} +/********************************************************************** + * PdxInitializeListener/1 PRIVATE + * + * DESCRIPTION + * Initialize a thread to make an LPC port listen. + */ +PRIVATE NTSTATUS STDCALL +PdxInitializeListener (ULONG ulIndex) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES Oa; + ULONG ulThreadIndex; + + RtlInitUnicodeString ( + & Server.Port[ulIndex].usName, + Server.Port[ulIndex].wsName + ); + InitializeObjectAttributes( + & Oa, + & Server.Port[ulIndex].usName, + 0, + NULL, + NULL + ); + /* Create the listening LPC port */ + Status = NtCreatePort ( + & Server.Port[ulIndex].hObject, + & Oa, + 260, + 328, + 0 + ); + if (!NT_SUCCESS(Status)) + { + debug_print( + L"PSXSS: Unable to create port \"%s\": Status %08x\n", + Server.Port[ulIndex].wsName, + Status); + return Status; + } + /* + * Create the server thread that will process + * messages sent to this port. + */ + for ( ulThreadIndex = 0; + (ulThreadIndex < PSXSS_THREADS_PER_PORT); + ulThreadIndex ++ + ) + { +#ifdef __PSXSS_ON_W32__ + Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject = + CreateThread ( + NULL, + 0, + (PTHREAD_START_ROUTINE) Server.Port[ulIndex].EntryPoint, + (PVOID) ulIndex, + CREATE_SUSPENDED, + & Server.Port[ulIndex].ThreadInfo[ulThreadIndex].Id + ); + if (NULL == Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject) +#else + if (!NT_SUCCESS(Status)) +#endif + { + debug_print( + L"PSXSS: Unable to create a server thread for port \"%s\": Status %08x\n", + Server.Port[ulIndex].wsName, + Status + ); + NtClose (Server.Port[ulIndex].hObject); + return Status; + } + } + return STATUS_SUCCESS; +} +/********************************************************************** + * PsxInitializeListeners/0 PRIVATE + * + * DESCRIPTION + * Initialize the LPC ports and associate threads. + */ +PRIVATE NTSTATUS STDCALL +PdxInitializeListeners (VOID) +{ + NTSTATUS Status; + ULONG ulIndex; + + for ( ulIndex = 0; + (ulIndex < (sizeof Server.Port / sizeof Server.Port[0])); + ulIndex ++) + { + Status = PdxInitializeListener (ulIndex); + if (!NT_SUCCESS(Status)) return Status; + } + return STATUS_SUCCESS; +} +/********************************************************************** + * PdxRunServer/0 PRIVATE + * + * DESCRIPTION + * Wake up all suspended threads. + */ +PRIVATE NTSTATUS STDCALL +PdxRunServer (VOID) +{ + NTSTATUS Status; + ULONG ulIndex; + ULONG ulThreadIndex; + + for ( ulIndex = 0; + (ulIndex < (sizeof Server.Port / sizeof Server.Port[0])); + ulIndex ++) + { + for (ulThreadIndex = 0; + (ulThreadIndex < PSXSS_THREADS_PER_PORT); + ulThreadIndex ++ + ) + { +#ifdef __PSXSS_ON_W32__ + if (0xFFFFFFFF == ResumeThread (Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject)) +#else + Status = NtResumeThread (Server.Port[ulIndex].ThreadInfo[ulThreadIndex].hObject, NULL); + if (!NT_SUCCESS(Status)) +#endif + { + debug_print( + L"PSXSS: "__FUNCTION__": NtResumeThread failed with Status = %08x", + Status + ); + return Status; + } + } + } + return STATUS_SUCCESS; +} +/********************************************************************** + * PsxServerInitialization/2 + * + * DESCRIPTION + * Initialize the PSX server process. + */ +NTSTATUS STDCALL +PsxServerInitialization ( + IN ULONG ArgumentCount, + IN PWSTR *ArgumentArray + ) +{ + NTSTATUS Status; + + /* Get our heap */ + PdxInitializeHeap (); + /* Initialize POSIX+ and Sessions */ + Status = PdxInitializeDirectories (); + if (!NT_SUCCESS(Status)) return Status; + /* LPCs dispatchers */ + Status = PdxInitializeListeners (); + if (!NT_SUCCESS(Status)) return Status; + /* Terminal manager */ + Status = PsxInitializeSessions (); + if (!NT_SUCCESS(Status)) return Status; + /* Process manager */ + Status = PsxInitializeProcesses (); + if (!NT_SUCCESS(Status)) return Status; + /* OK. Run! */ + Status = PdxRunServer (); + /* Done */ + return Status; +} +/* EOF */ diff --git a/posix/server/misc/main.c b/posix/server/misc/main.c new file mode 100644 index 00000000000..99760fe7ac7 --- /dev/null +++ b/posix/server/misc/main.c @@ -0,0 +1,89 @@ +/* $Id: main.c,v 1.1 2002/04/10 21:30:22 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/misc/main.c + * DESCRIPTION: POSIX+ server main. + * DATE : 2001-05-05 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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. + * + * -------------------------------------------------------------------- + * + * 19990605 (Emanuele Aliberti) + * Compiled successfully with egcs 1.1.2 + * 20020323 (Emanuele Aliberti) + * Converted to Win32 for testing it using NT LPC. + */ +#include +#include +#include + +/*** EXTERNAL ********************************************************/ + +NTSTATUS STDCALL +PsxServerInitialization ( + IN ULONG ArgumentCount, + IN PWSTR *ArgumentArray + ); + +/*** ENTRY POINT *****************************************************/ + +#ifdef __PSXSS_ON_W32__ // W32 PSXSS.EXE +int main (int argc, char * argv[]) +{ + INT c; + + debug_print(L"POSIX+ Subsystem for ReactOS "KERNEL_RELEASE_STR); + + if (STATUS_SUCCESS == PsxServerInitialization(0,NULL)) + { + debug_print(L"PSXSS: server active"); + while (TRUE) + { + c = getch(); + if (c == 1) break; + } + } + else + { + debug_print(L"PSXSS: Subsystem initialization failed.\n"); + } + return 0; +} +#else /* Native PSXSS.EXE */ +VOID NtProcessStartup (PPEB Peb) +{ + UNICODE_STRING Banner; + + RtlInitUnicodeString (& Banner, L"POSIX+ Subsystem for ReactOS "KERNEL_RELEASE_STR); + NtDisplayString(& Banner); + + if (STATUS_SUCCESS == PsxServerInitialization(0,NULL)) + { + DbgPrint("PSXSS: server active\n"); + /* TODO */ + } + else + { + DbgPrint("PSXSS: Subsystem initialization failed.\n"); + } + NtTerminateProcess (NtCurrentProcess(), 0); +} +#endif +/* EOF */ diff --git a/posix/server/misc/print.c b/posix/server/misc/print.c new file mode 100644 index 00000000000..115e1f20d16 --- /dev/null +++ b/posix/server/misc/print.c @@ -0,0 +1,18 @@ +/* $Id: print.c,v 1.1 2002/04/10 21:30:22 ea Exp $ */ +#define UNICODE +#include +VOID STDCALL debug_print (LPWSTR Template, ...) +{ + WCHAR Buffer [1024]; + va_list ArgumentPointer; + + va_start(ArgumentPointer, Template); + vswprintf(Buffer, Template, ArgumentPointer); + va_end(ArgumentPointer); +#ifdef __PSXSS_ON_W32__ + _putws (Buffer); +#else +#error TODO +#endif +} +/* EOF */ diff --git a/posix/server/misc/psxss.rc b/posix/server/misc/psxss.rc new file mode 100644 index 00000000000..2fa3b1f4c51 --- /dev/null +++ b/posix/server/misc/psxss.rc @@ -0,0 +1,39 @@ +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "POSIX+ Environment Subsystem Server\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "psxss\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "psxss.exe\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +/* EOF */ diff --git a/posix/server/ob/process.c b/posix/server/ob/process.c new file mode 100644 index 00000000000..983403da5ad --- /dev/null +++ b/posix/server/ob/process.c @@ -0,0 +1,56 @@ +/* $Id: process.c,v 1.1 2002/04/10 21:30:22 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/ob/session.c + * DESCRIPTION: terminal + * DATE : 2002-04-04 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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 + +/********************************************************************** + * PsxInitializeProcesses/0 + */ +NTSTATUS STDCALL +PsxInitializeProcesses (VOID) +{ + debug_print (L"PSXSS: ->"__FUNCTION__); + /* TODO */ + debug_print (L"PSXSS: <-"__FUNCTION__); + return STATUS_SUCCESS; +} +/********************************************************************** + * PsxCreateProcess/3 + */ +NTSTATUS STDCALL +PsxCreateProcess ( + PLPC_MAX_MESSAGE pRequest, + HANDLE hConnectedPort, + ULONG ulPortIdentifier + ) +{ + debug_print (L"PSXSS: ->"__FUNCTION__); + /* TODO */ + debug_print (L"PSXSS: <-"__FUNCTION__); + return STATUS_SUCCESS; +} +/* EOF */ diff --git a/posix/server/ob/session.c b/posix/server/ob/session.c new file mode 100644 index 00000000000..5555f0cb593 --- /dev/null +++ b/posix/server/ob/session.c @@ -0,0 +1,307 @@ +/* $Id: session.c,v 1.1 2002/04/10 21:30:22 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/ob/session.c + * DESCRIPTION: terminal + * DATE : 2002-04-04 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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 + +#define LOCK_ALL_SESSIONS RtlEnterCriticalSection(& Sessions.Lock) +#define UNLOCK_ALL_SESSIONS RtlLeaveCriticalSection(& Sessions.Lock) +#define LOCK_THIS_SESSION RtlEnterCriticalSection(& Session->Lock) +#define UNLOCK_THIS_SESSION RtlLeaveCriticalSection(& Session->Lock) + + +/* A double-linked list for the PSX_SESSION instances */ + +static struct +{ + ULONG NextFreeId; + LONG Count; + PPSX_SESSION List; + CRITICAL_SECTION Lock; + +} Sessions; + +/**** FUNCTIONS ******************************************************/ + +/********************************************************************** + * PsxInitializeSessions/0 + * + * DESCRIPTION + * Initialize the PSX session manager. + * ARGUMENTS + * None. + * RETURN VALUE + * None. + */ +NTSTATUS STDCALL +PsxInitializeSessions (VOID) +{ + debug_print (L"PSXSS: ->"__FUNCTION__); + /* Initalize the attributes */ + Sessions.NextFreeId = 0; + Sessions.Count = 0; + Sessions.List = NULL; + RtlInitializeCriticalSection (& Sessions.Lock); + return STATUS_SUCCESS; +} +/********************************************************************** + * PsxCreateSessionObjects/1 PRIVATE + * + */ +PRIVATE NTSTATUS STDCALL +PsxCreateSessionObjects ( + IN PLPC_MAX_MESSAGE pRequest, + IN OUT PPSX_SESSION pSession + ) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES Oa; + WCHAR NameBuffer [NAME_BUFFER_SIZE]; + UNICODE_STRING Name; + SECURITY_QUALITY_OF_SERVICE Sqos; + PSX_CONNECT_PORT_DATA ConnectData; + ULONG ConnectDataSize = sizeof ConnectData; + + /* Port */ + swprintf ( + NameBuffer, + PSX_NS_SESSION_PORT_TEMPLATE, + PSX_NS_SUBSYSTEM_DIRECTORY_NAME, + PSX_NS_SESSION_DIRECTORY_NAME, + pRequest->Header.Cid.UniqueProcess + ); + debug_print (L"PSXSS: "__FUNCTION__": %s", NameBuffer); + RtlInitUnicodeString (& Name, NameBuffer); + InitializeObjectAttributes (& Oa, & Name, 0, NULL, NULL); + RtlZeroMemory (& Sqos, sizeof Sqos); + ConnectData.ConnectionType = PSX_CONNECTION_TYPE_SERVER; + ConnectData.Version = PSX_LPC_PROTOCOL_VERSION; + ConnectData.PortIdentifier = 0; + Status = NtConnectPort ( + & pSession->TerminalChannel.hPort, + & Name, + & Sqos, + NULL, + NULL, + NULL, + (PVOID) & ConnectData, + & ConnectDataSize + ); + if (!NT_SUCCESS(Status)) + { + debug_print (L"PSXSS: "__FUNCTION__": NtConnectPort failed with %08x\n", Status); + return Status; + } + /* TODO: */ + /* Section */ + swprintf ( + NameBuffer, + PSX_NS_SESSION_DATA_TEMPLATE, + PSX_NS_SUBSYSTEM_DIRECTORY_NAME, + PSX_NS_SESSION_DIRECTORY_NAME, + pRequest->Header.Cid.UniqueProcess + ); + debug_print (L"PSXSS: "__FUNCTION__": %s", NameBuffer); + RtlInitUnicodeString (& Name, NameBuffer); + InitializeObjectAttributes (& Oa, & Name, 0, 0, 0); + Status = NtOpenSection ( + & pSession->TerminalChannel.Section.Handle, + SECTION_ALL_ACCESS, /* DesiredAccess */ + & Oa + ); + if (!NT_SUCCESS(Status)) + { + NtClose (pSession->TerminalChannel.hPort); + debug_print (L"PSXSS: "__FUNCTION__": NtOpenSection failed with %08x\n", Status); + return Status; + } + pSession->TerminalChannel.Section.BaseAddress = NULL; + pSession->TerminalChannel.Section.ViewSize = PSX_TERMINAL_SECTION_SIZE; + Status = NtMapViewOfSection ( + pSession->TerminalChannel.Section.Handle, + NtCurrentProcess(), + & pSession->TerminalChannel.Section.BaseAddress, + 0, /* ZeroBits */ + 0, /* Commitsize */ + 0, /* SectionOffset */ + & pSession->TerminalChannel.Section.ViewSize, + ViewUnmap, + 0, /* AllocationType */ + PAGE_READWRITE /* Protect 4 */ + ); + if (!NT_SUCCESS(Status)) + { + NtClose (pSession->TerminalChannel.hPort); + NtClose (pSession->TerminalChannel.Section.Handle); + debug_print (L"PSXSS: "__FUNCTION__": NtMapViewOfSection failed with %08x\n", Status); + return Status; + } + return Status; +} +/********************************************************************** + * PsxCreateSession/3 + * + * DESCRIPTION + * Create a new PSX_SESSION object and insert it in the + * PSX sessions table. + * ARGUMENTS + * MessageHeader + * Id + * RETURN VALUE + * A status value on error; otherwise STATUS_SUCCESS. + */ +NTSTATUS STDCALL +PsxCreateSession ( + IN PLPC_MAX_MESSAGE pRequest, + IN HANDLE hConnectedPort, + IN ULONG ulPortIdentifier + ) +{ + PPSX_SESSION Session = NULL; + + debug_print (L"PSXSS: ->"__FUNCTION__); + /* Create the PSX_SESSION object */ + Session = RtlAllocateHeap (Server.Heap, 0, sizeof (PSX_SESSION)); + if (NULL == Session) + { + debug_print (L"PSXSS: "__FUNCTION__": failed to create a new session object"); + return STATUS_MEMORY_NOT_ALLOCATED; + } + RtlZeroMemory (Session, sizeof (PSX_SESSION)); + /* Initialiaze the new PSX_SESSION object */ + Session->SessionChannel.hPort = hConnectedPort; + Session->SessionChannel.ulPortIdentifier = ulPortIdentifier; + LOCK_ALL_SESSIONS; + Session->Id = Sessions.NextFreeId ++; + UNLOCK_ALL_SESSIONS; + Session->Status = SESSION_STATUS_INITIALIZATION; + Session->Heap = + RtlCreateHeap ( + HEAP_GROWABLE, + NULL, + 65536, + 65536, + NULL, + NULL + ); + if (INVALID_HANDLE_VALUE == Session->Heap) + { + RtlFreeHeap (Server.Heap, 0, Session); + debug_print (L"PSX: "__FUNCTION__": failed to create a new heap for session # %d", Session->Id); + return STATUS_MEMORY_NOT_ALLOCATED; + } + RtlInitializeCriticalSection (& Session->Lock); + /* TODO: open the terminal's shared section */ + /* TODO: connect to the terminal's port */ + /* Inset the new PSX_SESSION object in the sessions table */ + LOCK_ALL_SESSIONS; + if (NULL == Sessions.List) + { + Sessions.List = Session; + Session->Previous = Session; + } + Session->Next = Sessions.List; /* Last one points to the top one */ + Session->Previous = Sessions.List->Previous; + Sessions.List->Previous = Session; /* Top one now points to the new one (tail) */ + ++ Sessions.Count; + UNLOCK_ALL_SESSIONS; + /* DONE */ + debug_print (L""__FUNCTION__": session # %d created", Session->Id); + Session->Status = SESSION_STATUS_READY; + return STATUS_SUCCESS; +} +/********************************************************************** + * PsxTerminateSession/1 + * + * DESCRIPTION + * Remove a PSX_SESSION object from the PSX sessions table and + * destroy it. + * + * ARGUMENTS + * + * RETURN VALUE + * A status value on error; otherwise STATUS_SUCCESS. + */ +NTSTATUS STDCALL +PsxTerminateSession ( + IN PPSX_SESSION Session + ) +{ + LONG Id; + PPSX_SESSION Previous = NULL; + PPSX_SESSION Next = NULL; + + /* Release any resource managed by the session */ + RtlDestroyHeap (Session->Heap); + /* Remove the session object from the sessions table */ + LOCK_ALL_SESSIONS; + Id = Session->Id; + Previous = Session->Previous; + Next = Session->Next; + /* TODO: handle the case of no session left */ + Next->Previous = Previous; + Previous->Next = Next; + -- Sessions.Count; + UNLOCK_ALL_SESSIONS; + /* Delete the old PSX_SESSION object */ + RtlFreeHeap (Server.Heap, 0, Session); + /* DONE */ + debug_print(L"PSX: session # %d deleted", Id); + return STATUS_SUCCESS; +} + +NTSTATUS STDCALL +PsxWriteTerminalSession ( + IN PPSX_SESSION Session, + IN PVOID Buffer, + IN ULONG Size, + IN OUT PULONG Written + ) +{ + LOCK_THIS_SESSION; + /* TODO: lock this session's section for writing */ + /* TODO: copy the data in this session's section */ + /* TODO: request a WRITE operation to the session terminal */ + /* TODO: unlock this session's section */ + UNLOCK_THIS_SESSION; +} + +NTSTATUS STDCALL +PsxReadTerminalSession ( + IN PPSX_SESSION Session, + OUT PVOID Buffer, + IN ULONG Size, + IN OUT PULONG Read + ) +{ + LOCK_THIS_SESSION; + /* TODO: lock this session's section for reading */ + /* TODO: request a READ operation to the session terminal */ + /* TODO: copy the data from this session's section */ + /* TODO: unlock this session's section */ + UNLOCK_THIS_SESSION; +} +/* EOF */ diff --git a/posix/server/ob/terminal.c b/posix/server/ob/terminal.c new file mode 100644 index 00000000000..b456c8c09d8 --- /dev/null +++ b/posix/server/ob/terminal.c @@ -0,0 +1,56 @@ +/* $Id: terminal.c,v 1.1 2002/04/10 21:30:22 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/ob/terminal.c + * DESCRIPTION: terminal + * DATE : 2002-04-04 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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 + +/********************************************************************** + * WriteTerminal/4 + */ +NTSTATUS STDCALL +WriteTerminal ( + IN PPSX_TERMINAL Terminal, + IN PVOID Buffer, + IN ULONG Size, + IN OUT PULONG WrittenSize + ) +{ + return STATUS_NOT_IMPLEMENTED; +} +/********************************************************************** + * ReadTerminal/4 + */ +NTSTATUS STDCALL +ReadTerminal ( + IN PPSX_TERMINAL Terminal, + IN OUT PVOID Buffer, + IN ULONG Size, + IN OUT PULONG ReadSize + ) +{ + return STATUS_NOT_IMPLEMENTED; +} +/* EOF */ diff --git a/posix/server/port/api.c b/posix/server/port/api.c new file mode 100644 index 00000000000..c72af1614b1 --- /dev/null +++ b/posix/server/port/api.c @@ -0,0 +1,195 @@ +/* $Id: api.c,v 1.1 2002/04/10 21:30:22 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 + * + * -------------------------------------------------------------------- + * + * 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 +#include +#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: ->"__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: "__FUNCTION__": NtAcceptConnectPort failed with status=%08x", + 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: "__FUNCTION__": NtAcceptConnectPort failed with status=%08x", Status); + return Status; + } + Status = PsxCreateProcess (pRequest,hConnectedPort,ulPortIdentifier); + if (!NT_SUCCESS(Status)) + { + debug_print(L"PSXSS: "__FUNCTION__": PsxCreateProcess failed with status=%08x", Status); + return Status; + } + Status = NtCompleteConnectPort (hConnectedPort); + if (!NT_SUCCESS(Status)) + { + debug_print(L"PSXSS: "__FUNCTION__": NtCompleteConnectPort failed with status=%08x", Status); + return Status; + } + debug_print (L"PSXSS: <-"__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: ->"__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: ->"__FUNCTION__" pArg=%d", 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 */ diff --git a/posix/server/port/sbapi.c b/posix/server/port/sbapi.c new file mode 100644 index 00000000000..7894f330909 --- /dev/null +++ b/posix/server/port/sbapi.c @@ -0,0 +1,76 @@ +/* $Id: sbapi.c,v 1.1 2002/04/10 21:30:22 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/port/sbapi.c + * DESCRIPTION: \POSIX+\SbApiPort LPC logic. + * DATE : 2001-03-23 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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 +#include "utils.h" + + +/********************************************************************** + * ProcessConnectionRequest/ PRIVATE + */ +PRIVATE NTSTATUS STDCALL +ProcessConnectionRequest (PPSX_MESSAGE pRequest) +{ + return STATUS_NOT_IMPLEMENTED; +} +/********************************************************************** + * ProcessRequest/ PRIVATE + */ +PRIVATE NTSTATUS STDCALL +ProcessRequest (PPSX_MESSAGE pRequest) +{ + return STATUS_NOT_IMPLEMENTED; +} +/********************************************************************** + * SbApiPortListener/1 + * + * DESCRIPTION + * The \POSIX+\SbApiPort LPC port message dispatcher. + * + * NOTE + * what is this port for? Is "Sb" for "shared block"? + */ +VOID STDCALL +SbApiPortListener (PVOID pArg) +{ + NTSTATUS Status; + ULONG PortIdentifier; + PSX_MAX_MESSAGE Request; + PPSX_MAX_MESSAGE Reply = NULL; + + debug_print (L"PSXSS: ->"__FUNCTION__" pArg=%d", (ULONG) pArg); + + RtlZeroMemory (& Request, sizeof Request); + /* TODO */ +#ifdef __PSXSS_ON_W32__ + Sleep(30000); + TerminateThread(GetCurrentThread(),Status); +#else + NtTerminateThread(NtCurrentThread(),Status); +#endif +} +/* EOF */ diff --git a/posix/server/port/session.c b/posix/server/port/session.c new file mode 100644 index 00000000000..2a7c940822b --- /dev/null +++ b/posix/server/port/session.c @@ -0,0 +1,194 @@ +/* $Id: session.c,v 1.1 2002/04/10 21:30:22 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/port/session.c + * DESCRIPTION: \POSIX+\SessionPort LPC port logic. + * DATE : 2002-04-04 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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 +#include +#include "utils.h" + +/********************************************************************** + * ProcessConnectionRequest/ PRIVATE + */ +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: ->"__FUNCTION__); + + /* Check if the caller is a terminal */ + Status = PsxCheckConnectionRequest ( + pConnectData, + PSX_CONNECTION_TYPE_TERMINAL + ); + if (!NT_SUCCESS(Status)) + { + Status = NtAcceptConnectPort ( + & hConnectedPort, + NULL, + & pRequest->Header, + FALSE, /* reject connection request */ + NULL, + NULL + ); + if (!NT_SUCCESS(Status)) + { + debug_print( + L"PSXSS: "__FUNCTION__": NtAcceptConnectPort failed with status=%08x", + 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: "__FUNCTION__": NtAcceptConnectPort failed with status=%08x", Status); + return Status; + } + /* OK, now create a new PSX_SESSION object */ + Status = PsxCreateSession ( + pRequest, + hConnectedPort, + ulPortIdentifier + ); + if (!NT_SUCCESS(Status)) + { + debug_print(L"PSXSS: "__FUNCTION__": PsxCreateSession failed with status=%08x", Status); + return Status; + } + Status = NtCompleteConnectPort (hConnectedPort); + if (!NT_SUCCESS(Status)) + { + debug_print(L"PSXSS: "__FUNCTION__": NtCompleteConnectPort failed with status=%08x", Status); + return Status; + } + debug_print (L"PSXSS: <-"__FUNCTION__); + return STATUS_SUCCESS; +} +/********************************************************************** + * ProcessRequest/ PRIVATE + */ +PRIVATE NTSTATUS STDCALL +ProcessRequest (PPSX_MAX_MESSAGE pRequest) +{ + debug_print (L"PSXSS: ->"__FUNCTION__); + /* TODO: Read data from the section */ + /* TODO: send data to the process */ + debug_print (L"PSXSS: <-"__FUNCTION__); + return STATUS_NOT_IMPLEMENTED; +} +/********************************************************************** + * SessionPortListener/1 + * + * DESCRIPTION + * Listen on port \POSIX+\SessionPort and create new sessions + * when a new terminal emulator calls. + * + * ARGUMENTS + * \POSIX+\SessionPort handle. + * + * RETURN VALUE + * None. + */ +VOID STDCALL +SessionPortListener (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: ->"__FUNCTION__" pArg=%d", 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 */ diff --git a/posix/server/port/utils.c b/posix/server/port/utils.c new file mode 100644 index 00000000000..92877583c0e --- /dev/null +++ b/posix/server/port/utils.c @@ -0,0 +1,67 @@ +/* $Id: utils.c,v 1.1 2002/04/10 21:30:22 ea Exp $ + * + * PROJECT : ReactOS / POSIX+ Environment Subsystem Server + * FILE : reactos/subsys/psx/server/port/utils.c + * DESCRIPTION: LPC port utilities. + * DATE : 2002-04-07 + * AUTHOR : Emanuele Aliberti + * + * -------------------------------------------------------------------- + * + * 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 +#include "utils.h" + +/********************************************************************** + * PsxCheckConnectionRequest/2 + * + * DESCRIPTION + * Check if we can accept the connection request sent to + * an LPC port. Protocol version and ConnectionType MUST match. + */ +NTSTATUS STDCALL +PsxCheckConnectionRequest ( + IN OUT PPSX_CONNECT_PORT_DATA pConnectData, + IN PSX_CONNECTION_TYPE ConnectionType + ) +{ + /* Check if the caller is ConnectionType */ + if (ConnectionType != pConnectData->ConnectionType) + { + debug_print( + L"PSXSS: "__FUNCTION__": ConnectionType=%d, expected %d", + pConnectData->ConnectionType, + ConnectionType + ); + return STATUS_UNSUCCESSFUL; + } + /* Check if the LPC protocol version matches */ + if (PSX_LPC_PROTOCOL_VERSION != pConnectData->Version) + { + debug_print( + L"PSXSS: "__FUNCTION__": Version=%d, expected %d", + pConnectData->Version, + PSX_LPC_PROTOCOL_VERSION + ); + pConnectData->Version = PSX_LPC_PROTOCOL_VERSION; + return STATUS_UNSUCCESSFUL; + } + return STATUS_SUCCESS; +} +/* EOF */ diff --git a/posix/server/port/utils.h b/posix/server/port/utils.h new file mode 100644 index 00000000000..fe17468cd23 --- /dev/null +++ b/posix/server/port/utils.h @@ -0,0 +1,4 @@ +#ifndef _UTILS_H +#define _UTILS_H +NTSTATUS STDCALL PsxCheckConnectionRequest (PPSX_CONNECT_PORT_DATA,PSX_CONNECTION_TYPE); +#endif