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

321 lines
8.6 KiB
C

/* $Id: init.c,v 1.3 2002/10/29 04:45:54 rex 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 <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 <napi/teb.h>
#ifdef __PSXSS_ON_W32__
#include <windows.h>
#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 */