reactos/posix/server/ob/session.c
2002-10-29 04:45:58 +00:00

308 lines
9.7 KiB
C

/* $Id: session.c,v 1.3 2002/10/29 04:45:54 rex 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 */