reactos/posix/server/ob/session.c
Emanuele Aliberti bb24d01a48 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
2002-04-10 21:30:22 +00:00

308 lines
9.7 KiB
C

/* $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 <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>
#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 */