SM: subsystem registration (partial)
- merged duplicate code in process creation
- experimental implementation of env subsystem registration
Modified: trunk/reactos/subsys/smss/client.c
Modified: trunk/reactos/subsys/smss/initdosdev.c
Modified: trunk/reactos/subsys/smss/initreg.c
Modified: trunk/reactos/subsys/smss/initrun.c
Modified: trunk/reactos/subsys/smss/initss.c
Modified: trunk/reactos/subsys/smss/makefile
Added: trunk/reactos/subsys/smss/print.c
Modified: trunk/reactos/subsys/smss/smapi.c
Added: trunk/reactos/subsys/smss/smapicomp.c
Added: trunk/reactos/subsys/smss/smapiexec.c
Modified: trunk/reactos/subsys/smss/smss.c
Modified: trunk/reactos/subsys/smss/smss.h

Modified: trunk/reactos/subsys/smss/client.c
--- trunk/reactos/subsys/smss/client.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/client.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -26,6 +26,7 @@
 #define NTOS_MODE_USER
 #include <ntos.h>
 #include "smss.h"
+#include <sm/helper.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -41,7 +42,40 @@
 
 } SmpClientDirectory;
 
+#if 0
 /**********************************************************************
+ *	SmpRegisterSmss/0
+ */
+static NTSTATUS
+SmpRegisterSmss(VOID)
+{
+	NTSTATUS Status = STATUS_SUCCESS;
+	UNICODE_STRING SbApiPortName = {0,0,NULL};
+	HANDLE hSmApiPort = (HANDLE) 0;
+
+	DPRINT("SM: %s called\n",__FUNCTION__);
+	
+	Status = SmConnectApiPort(& SbApiPortName,
+				  (HANDLE) -1,
+				  IMAGE_SUBSYSTEM_NATIVE,
+				  & hSmApiPort);
+	if(!NT_SUCCESS(Status))
+	{
+		DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",__FUNCTION__,Status);
+		return Status;
+	}
+	Status = SmCompleteSession (hSmApiPort, (HANDLE)0, hSmApiPort);
+	if(!NT_SUCCESS(Status))
+	{
+		DPRINT("SM: %s: SMDLL!SmCompleteSession failed (Status=0x%08lx)\n",__FUNCTION__,Status);
+		return Status;
+	}
+	NtClose(hSmApiPort);
+	return Status;
+}
+#endif
+
+/**********************************************************************
  *	SmInitializeClientManagement/0
  */
 NTSTATUS
@@ -51,11 +85,22 @@
 	RtlInitializeCriticalSection(& SmpClientDirectory.Lock);
 	SmpClientDirectory.Count = 0;
 	SmpClientDirectory.Client = NULL;
+#if 0
+	/* Register IMAGE_SUBSYSTE_NATIVE to be managed by SM */
+	return SmpRegisterSmss();
+#endif
 	return STATUS_SUCCESS;
+
 }
 
 /**********************************************************************
  *	SmpLookupClient/1
+ *
+ * DESCRIPTION
+ * 	Lookup the subsystem server descriptor given its image ID.
+ *
+ * SIDE EFFECTS
+ * 	SmpClientDirectory.Lock is released only on success.
  */
 static PSM_CLIENT_DATA STDCALL
 SmpLookupClient (USHORT SubsystemId)
@@ -70,22 +115,31 @@
 		Client = SmpClientDirectory.Client;
 		while (NULL != Client)
 		{
-			if (SubsystemId == Client->SubsystemId) break;
+			if (SubsystemId == Client->SubsystemId)
+			{
+				RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+				return Client;
+			}
 			Client = Client->Next;
 		}
 	}
-	RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+	/*
+	 * Note that we do *not* release SmpClientDirectory.Lock here
+	 * because SmpLookupClient is called to FAIL when SubsystemId
+	 * is not registered yet.
+	 */
 	return Client;
 }
 
 /**********************************************************************
- *	SmpCreateClient/1
+ *	SmpCreateClient/2
  */
 NTSTATUS STDCALL
 SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
 {
 	PSM_CLIENT_DATA pClient = NULL;
 	PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);
+	ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);
 
 	DPRINT("SM: %s called\n", __FUNCTION__);
 
@@ -94,9 +148,12 @@
 	 */
 	if (SmpLookupClient(ConnectData->Subsystem))
 	{
-		DbgPrint("SMSS: %s: attempt to register again subsystem %d.\n",__FUNCTION__,0);
+		DPRINT("SMSS: %s: attempt to register again subsystem %d.\n",
+			__FUNCTION__,
+			ConnectData->Subsystem);
 		return STATUS_UNSUCCESSFUL;
 	}
+	DPRINT("SM: %s: registering subsystem %d \n", __FUNCTION__, ConnectData->Subsystem);
 	/*
 	 * Allocate the storage for client data
 	 */
@@ -112,13 +169,17 @@
 	 * Initialize the client data
 	 */
 	pClient->SubsystemId = ConnectData->Subsystem;
-	pClient->Initialized = FALSE;
-	// TODO
+	pClient->Initialized = (IMAGE_SUBSYSTEM_NATIVE == pClient->SubsystemId);
+	if (SbApiPortNameSize > 0)
+	{
+		RtlCopyMemory (pClient->SbApiPortName,
+			       ConnectData->SbName,
+			       SbApiPortNameSize);
+	}
 	/*
 	 * Insert the new descriptor in the
 	 * client directory.
 	 */
-	RtlEnterCriticalSection (& SmpClientDirectory.Lock);
 	if (NULL == SmpClientDirectory.Client)
 	{
 		SmpClientDirectory.Client = pClient;
@@ -132,8 +193,15 @@
 	}
 	pClient->Next = NULL;
 	++ SmpClientDirectory.Count;
+	/*
+	 * Note we unlock the client directory here, because
+	 * it was locked by SmpLookupClient on failure.
+	 */
 	RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
-	if (ClientData) *ClientData = pClient;
+	if (ClientData) 
+	{
+		*ClientData = pClient;
+	}
 	return STATUS_SUCCESS;
 }
 

Modified: trunk/reactos/subsys/smss/initdosdev.c
--- trunk/reactos/subsys/smss/initdosdev.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/initdosdev.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -1,6 +1,6 @@
 /* $Id: init.c 13449 2005-02-06 21:55:07Z ea $
  *
- * initdosdev.c - Define symbolic links to kernel devices (MS-DOS names)
+ * initdosdev.c - Define symbolic links to kernel devices (MS-DOS names).
  * 
  * ReactOS Operating System
  * 

Modified: trunk/reactos/subsys/smss/initreg.c
--- trunk/reactos/subsys/smss/initreg.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/initreg.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -1,6 +1,6 @@
 /* $Id: init.c 13449 2005-02-06 21:55:07Z ea $
  *
- * initenv.c - Environment initialization
+ * initenv.c - Hive loading
  * 
  * ReactOS Operating System
  * 

Modified: trunk/reactos/subsys/smss/initrun.c
--- trunk/reactos/subsys/smss/initrun.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/initrun.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -32,6 +32,9 @@
 HANDLE Children[2] = {0, 0}; /* csrss, winlogon */
 
 
+/**********************************************************************
+ * SmpRunBootAppsQueryRoutine/6
+ */
 static NTSTATUS STDCALL
 SmpRunBootAppsQueryRoutine(PWSTR ValueName,
 			  ULONG ValueType,
@@ -40,14 +43,10 @@
 			  PVOID Context,
 			  PVOID EntryContext)
 {
-  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
-  RTL_PROCESS_INFO ProcessInfo;
-  UNICODE_STRING ImagePathString;
-  UNICODE_STRING CommandLineString;
-  WCHAR Description[256];
-  WCHAR ImageName[256];
-  WCHAR ImagePath[256];
-  WCHAR CommandLine[256];
+  WCHAR Description [MAX_PATH];
+  WCHAR ImageName [MAX_PATH];
+  WCHAR ImagePath [MAX_PATH];
+  WCHAR CommandLine [MAX_PATH];
   PWSTR p1, p2;
   ULONG len;
   NTSTATUS Status;
@@ -96,54 +95,23 @@
   wcscat(ImagePath, ImageName);
   wcscat(ImagePath, L".exe");
 
-  RtlInitUnicodeString(&ImagePathString,
-		       ImagePath);
-
-  RtlInitUnicodeString(&CommandLineString,
-		       CommandLine);
-
-  RtlCreateProcessParameters(&ProcessParameters,
-			     &ImagePathString,
-			     NULL,
-			     NULL,
-			     &CommandLineString,
-			     NULL,
-			     NULL,
-			     NULL,
-			     NULL,
-			     NULL);
-
-  Status = RtlCreateUserProcess(&ImagePathString,
-				OBJ_CASE_INSENSITIVE,
-				ProcessParameters,
+  /* Create NT process */
+  Status = SmCreateUserProcess (ImagePath,
+		  		CommandLine,
+				TRUE, /* wait */
 				NULL,
-				NULL,
-				NULL,
-				FALSE,
-				NULL,
-				NULL,
-				&ProcessInfo);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("Running %s failed (Status %lx)\n", Description, Status);
-      return(STATUS_SUCCESS);
-    }
+				TRUE, /* terminate */
+				NULL);
 
-  RtlDestroyProcessParameters(ProcessParameters);
-
-  /* Wait for process termination */
-  NtWaitForSingleObject(ProcessInfo.ProcessHandle,
-			FALSE,
-			NULL);
-
-  NtClose(ProcessInfo.ThreadHandle);
-  NtClose(ProcessInfo.ProcessHandle);
-
   return(STATUS_SUCCESS);
 }
 
 
-/*
+/**********************************************************************
+ * SmRunBootApplications/0
+ * 
+ * DESCRIPTION
+ *
  * Run native applications listed in the registry.
  *
  *  Key:

Modified: trunk/reactos/subsys/smss/initss.c
--- trunk/reactos/subsys/smss/initss.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/initss.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -26,6 +26,7 @@
 
 
 #include "smss.h"
+
 #include <rosrtl/string.h>
 
 #define NDEBUG
@@ -49,6 +50,9 @@
  * e) make optional subsystems loadable (again: they must be described in the registry
  *    key Optional="Posix Os2" to be allowed to run)
  */
+
+/**********************************************************************
+ */
 NTSTATUS
 SmLoadSubsystems(VOID)
 {
@@ -56,7 +60,7 @@
   NTSTATUS Status;
 
   DPRINT("SM: loading subsystems\n");
-
+ 
   /* Load kernel mode subsystem (aka win32k.sys) */
   RtlRosInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
 		       L"\\SystemRoot\\system32\\win32k.sys");
@@ -84,10 +88,9 @@
   NTSTATUS Status;
   UNICODE_STRING UnicodeString;
   OBJECT_ATTRIBUTES ObjectAttributes;
-  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
   RTL_PROCESS_INFO ProcessInfo;
   HANDLE CsrssInitEvent;
-  WCHAR UnicodeBuffer[MAX_PATH];
+  WCHAR ImagePath [MAX_PATH];
 
   DPRINT("SM: initializing csrss\n");
 
@@ -114,36 +117,17 @@
    */
 
   /* initialize executable path */
-  wcscpy(UnicodeBuffer, L"\\??\\");
-  wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
-  wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
-  RtlInitUnicodeString(&UnicodeString,
-		       UnicodeBuffer);
+  wcscpy(ImagePath, L"\\??\\");
+  wcscat(ImagePath, SharedUserData->NtSystemRoot);
+  wcscat(ImagePath, L"\\system32\\csrss.exe");
 
-  RtlCreateProcessParameters(&ProcessParameters,
-			     &UnicodeString,
-			     NULL,
-			     NULL,
-			     NULL,
-			     SmSystemEnvironment,
-			     NULL,
-			     NULL,
-			     NULL,
-			     NULL);
-
-  Status = RtlCreateUserProcess(&UnicodeString,
-				OBJ_CASE_INSENSITIVE,
-				ProcessParameters,
+  Status = SmCreateUserProcess(ImagePath,
+		  		L"",
+				FALSE, /* wait */
 				NULL,
-				NULL,
-				NULL,
-				FALSE,
-				NULL,
-				NULL,
-				&ProcessInfo);
-
-  RtlDestroyProcessParameters (ProcessParameters);
-
+				FALSE, /* terminate */
+				& ProcessInfo);
+  
   if (!NT_SUCCESS(Status))
     {
       DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__);
@@ -162,11 +146,9 @@
 NTSTATUS
 SmRunWinlogon(VOID)
 {
-  NTSTATUS Status;
-  UNICODE_STRING UnicodeString;
-  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+  NTSTATUS         Status = STATUS_SUCCESS;
   RTL_PROCESS_INFO ProcessInfo;
-  WCHAR UnicodeBuffer[MAX_PATH];
+  WCHAR            ImagePath [MAX_PATH];
 
   /*
    * Start the logon process (winlogon.exe)
@@ -175,43 +157,23 @@
   DPRINT("SM: starting winlogon\n");
 
   /* initialize executable path */
-  wcscpy(UnicodeBuffer, L"\\??\\");
-  wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
-  wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
-  RtlInitUnicodeString(&UnicodeString,
-		       UnicodeBuffer);
+  wcscpy(ImagePath, L"\\??\\");
+  wcscat(ImagePath, SharedUserData->NtSystemRoot);
+  wcscat(ImagePath, L"\\system32\\winlogon.exe");
 
-  RtlCreateProcessParameters(&ProcessParameters,
-			     &UnicodeString,
-			     NULL,
-			     NULL,
-			     NULL,
-			     SmSystemEnvironment,
-			     NULL,
-			     NULL,
-			     NULL,
-			     NULL);
-
-  Status = RtlCreateUserProcess(&UnicodeString,
-				OBJ_CASE_INSENSITIVE,
-				ProcessParameters,
+  Status = SmCreateUserProcess(ImagePath,
+		  		L"",
+				FALSE, /* wait */
 				NULL,
-				NULL,
-				NULL,
-				FALSE,
-				NULL,
-				NULL,
-				&ProcessInfo);
-
-  RtlDestroyProcessParameters(ProcessParameters);
-
+				FALSE, /* terminate */
+		  		& ProcessInfo);
   if (!NT_SUCCESS(Status))
     {
       DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);
-      NtTerminateProcess(Children[CHILD_CSRSS],
-			 0);
+      NtTerminateProcess(Children[CHILD_CSRSS], 0);
       return(Status);
     }
+
   Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
 
   return Status;

Modified: trunk/reactos/subsys/smss/makefile
--- trunk/reactos/subsys/smss/makefile	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/makefile	2005-02-19 22:58:18 UTC (rev 13654)
@@ -6,6 +6,8 @@
 
 TARGET_APPTYPE = native
 
+TARGET_SDKLIBS = ntdll.a smdll.a
+
 TARGET_NAME = smss
 
 TARGET_INSTALLDIR = system32
@@ -19,8 +21,8 @@
 		 init.o initheap.o initenv.o initobdir.o initdosdev.o \
 		 initrun.o initmv.o initwkdll.o initpage.o initss.o \
 		 initreg.o \
-		 smapi.o \
-		 client.o debug.o
+		 smapi.o smapicomp.o smapiexec.o \
+		 client.o debug.o print.o
 
 include $(PATH_TO_TOP)/rules.mak
 

Added: trunk/reactos/subsys/smss/print.c
--- trunk/reactos/subsys/smss/print.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/print.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -0,0 +1,56 @@
+/* $Id: print.c 12852 2005-01-06 13:58:04Z mf $
+ *
+ * print.c - Print on the blue screen
+ * 
+ * ReactOS Operating System
+ * 
+ * --------------------------------------------------------------------
+ *
+ * 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.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.  
+ *
+ * --------------------------------------------------------------------
+ */
+#define NTOS_MODE_USER
+#include <ntos.h>
+
+VOID STDCALL DisplayString(LPCWSTR lpwString)
+{
+   UNICODE_STRING us;
+   
+   RtlInitUnicodeString (&us, lpwString);
+   ZwDisplayString (&us);
+}
+
+VOID STDCALL PrintString (char* fmt, ...)
+{
+   char buffer[512];
+   va_list ap;
+   UNICODE_STRING UnicodeString;
+   ANSI_STRING AnsiString;
+   
+   va_start(ap, fmt);
+   vsprintf(buffer, fmt, ap);
+   va_end(ap);
+   
+   RtlInitAnsiString (&AnsiString, buffer);
+   RtlAnsiStringToUnicodeString (&UnicodeString,
+				 &AnsiString,
+				 TRUE);
+   NtDisplayString(&UnicodeString);
+   RtlFreeUnicodeString (&UnicodeString);
+}
+
+/* EOF */

Modified: trunk/reactos/subsys/smss/smapi.c
--- trunk/reactos/subsys/smss/smapi.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/smapi.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -9,7 +9,7 @@
 #include "smss.h"
 #include <rosrtl/string.h>
 
-#define NDEBUG
+//#define NDEBUG
 #include <debug.h>
 
 /* GLOBAL VARIABLES *********************************************************/
@@ -18,9 +18,6 @@
 
 /* SM API *******************************************************************/
 
-#define SMAPI(n) \
-NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request)
-
 SMAPI(SmInvalid)
 {
 	DPRINT("SM: %s called\n",__FUNCTION__);
@@ -28,89 +25,193 @@
 	return STATUS_SUCCESS;
 }
 
-SMAPI(SmCompSes)
-{
-	DPRINT("SM: %s called\n",__FUNCTION__);
-	Request->Status = STATUS_NOT_IMPLEMENTED;
-	return STATUS_SUCCESS;
-}
-SMAPI(SmExecPgm)
-{
-	DPRINT("SM: %s called\n",__FUNCTION__);
-	Request->Status = STATUS_NOT_IMPLEMENTED;
-	return STATUS_SUCCESS;
-}
-
 /* SM API Table */
 typedef NTSTATUS (FASTCALL * SM_PORT_API)(PSM_PORT_MESSAGE);
 
 SM_PORT_API SmApi [] =
 {
 	SmInvalid,	/* unused */
-	SmCompSes,
+	SmCompSes,	/* smapicomp.c */
 	SmInvalid,	/* obsolete */
 	SmInvalid,	/* unknown */
-	SmExecPgm
+	SmExecPgm	/* smapiexec.c */
 };
 
+#if !defined(__USE_NT_LPC__)
+NTSTATUS STDCALL
+SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request);
+#endif
 
+
 /**********************************************************************
  * NAME
- *	SmpHandleConnectionRequest/2
+ * 	SmpApiConnectedThread/1
  *
+ * DESCRIPTION
+ * 	Entry point for the listener thread of LPC port "\SmApiPort".
+ */
+VOID STDCALL
+SmpApiConnectedThread(PVOID dummy)
+{
+	NTSTATUS	Status = STATUS_SUCCESS;
+	PVOID		Unknown = NULL;
+	PLPC_MESSAGE	Reply = NULL;
+	SM_PORT_MESSAGE	Request = {{0}};
+
+	DPRINT("SM: %s running\n",__FUNCTION__);
+
+	while (TRUE)
+	{
+		DPRINT("SM: %s: waiting for message\n",__FUNCTION__);
+
+		Status = NtReplyWaitReceivePort(SmApiPort,
+						(PULONG) & Unknown,
+						Reply,
+						(PLPC_MESSAGE) & Request);
+		if (NT_SUCCESS(Status))
+		{
+			DPRINT("SM: %s: message received (type=%d)\n",
+				__FUNCTION__,
+				PORT_MESSAGE_TYPE(Request));
+
+			switch (Request.Header.MessageType)
+			{
+			case LPC_CONNECTION_REQUEST:
+				SmpHandleConnectionRequest (&Request);
+				Reply = NULL;
+				break;
+			case LPC_DEBUG_EVENT:
+//				DbgSsHandleKmApiMsg (&Request, 0);
+				Reply = NULL;
+				break;
+			case LPC_PORT_CLOSED:
+			      Reply = NULL;
+			      break;
+			default:
+				if ((Request.ApiIndex) &&
+					(Request.ApiIndex < (sizeof SmApi / sizeof SmApi[0])))
+				{
+					Status = SmApi[Request.ApiIndex](&Request);
+				      	Reply = (PLPC_MESSAGE) & Request;
+				} else {
+					Request.Status = STATUS_NOT_IMPLEMENTED;
+					Reply = (PLPC_MESSAGE) & Request;
+				}
+			}
+		}
+	}
+}
+
+/**********************************************************************
+ * NAME
+ *	SmpHandleConnectionRequest/1
+ *
+ * ARGUMENTS
+ * 	Request: LPC connection request message
+ *
  * REMARKS
  * 	Quoted in http://support.microsoft.com/kb/258060/EN-US/
  */
 NTSTATUS STDCALL
-SmpHandleConnectionRequest (HANDLE Port, PSM_PORT_MESSAGE Request)
+SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
 {
+#if defined(__USE_NT_LPC__)
 	NTSTATUS         Status = STATUS_SUCCESS;
 	PSM_CLIENT_DATA  ClientData = NULL;
 	PVOID            Context = NULL;
 	
 	DPRINT("SM: %s called\n",__FUNCTION__);
 
+	/*
+	 * SmCreateClient/2 is called here explicitly to *fail*.
+	 * If it succeeds, there is something wrong in the
+	 * connection request. An environment subsystem *never*
+	 * registers twice. (Security issue: maybe we will
+	 * write this event into the security log).
+	 */
 	Status = SmCreateClient (Request, & ClientData);
 	if(STATUS_SUCCESS == Status)
 	{
-#ifdef __USE_NT_LPC__
+		/* OK: the client is an environment subsystem
+		 * willing to manage a free image type.
+		 * Accept it.
+		 */
 		Status = NtAcceptConnectPort (& ClientData->ApiPort,
 					      Context,
-					      SmApiPort,
+					      (PLPC_MESSAGE) Request,
 					      TRUE, //accept
 					      NULL,
 					      NULL);
-#else
+		if(NT_SUCCESS(Status))
+		{
+			Status = NtCompleteConnectPort(ClientData->ApiPort);
+		}
+		return STATUS_SUCCESS;
+	} else {
+		/* Reject the subsystem */
 		Status = NtAcceptConnectPort (& ClientData->ApiPort,
 					      Context,
 					      (PLPC_MESSAGE) Request,
+					      FALSE, //reject
+					      NULL,
+					      NULL);
+	}
+#else /* ReactOS LPC */
+	NTSTATUS         Status = STATUS_SUCCESS;
+	PSM_CLIENT_DATA  ClientData = NULL;
+	
+	DPRINT("SM: %s called\n",__FUNCTION__);
+
+	Status = SmCreateClient (Request, & ClientData);
+	if(STATUS_SUCCESS == Status)
+	{
+		Status = NtAcceptConnectPort (& ClientData->ApiPort,
+					      SmApiPort,
+					      NULL,
 					      TRUE, //accept
 					      NULL,
 					      NULL);
-#endif
-		if(NT_SUCCESS(Status))
+		if (!NT_SUCCESS(Status))
 		{
+			DPRINT1("SM: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
+					__FUNCTION__, Status);
+			return Status;
+		} else {
 			Status = NtCompleteConnectPort(ClientData->ApiPort);
+			if (!NT_SUCCESS(Status))
+			{
+				DPRINT1("SM: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
+					__FUNCTION__, Status);
+				return Status;
+			}
+			Status = RtlCreateUserThread(NtCurrentProcess(),
+					     NULL,
+					     FALSE,
+					     0,
+					     NULL,
+					     NULL,
+					     (PTHREAD_START_ROUTINE) SmpApiConnectedThread,
+					     ClientData->ApiPort,
+					     & ClientData->ApiPortThread,
+					     NULL);
+			if (!NT_SUCCESS(Status))
+			{
+				DPRINT1("SM: %s: Unable to create server thread (Status=0x%08lx)\n",
+					__FUNCTION__, Status);
+				return Status;
+			}
 		}
 		return STATUS_SUCCESS;
 	} else {
 		/* Reject the subsystem */
-#ifdef __USE_NT_LPC__
 		Status = NtAcceptConnectPort (& ClientData->ApiPort,
-					      Context,
 					      SmApiPort,
-					      FALSE, //reject
 					      NULL,
-					      NULL);
-#else
-		Status = NtAcceptConnectPort (& ClientData->ApiPort,
-					      Context,
-					      (PLPC_MESSAGE) Request,
 					      FALSE, //reject
 					      NULL,
 					      NULL);
-#endif
 	}
+#endif /* defined __USE_NT_LPC__ */
 	return Status;
 }
 
@@ -118,59 +219,39 @@
  * NAME
  * 	SmpApiThread/1
  *
- * DESCRIPTION
- * 	Entry point for the listener thread of LPC port "\SmApiPort".
+ * DECRIPTION
+ * 	Due to differences in LPC implementation between NT and ROS,
+ * 	we need a thread to listen for connection request that
+ * 	creates a new thread for each connected port. This is not
+ * 	necessary in NT LPC, because server side connected ports are
+ * 	never used to receive requests. 
  */
 VOID STDCALL
-SmpApiThread(HANDLE Port)
+SmpApiThread (HANDLE ListeningPort)
 {
 	NTSTATUS	Status = STATUS_SUCCESS;
-	PVOID		Unknown = NULL;
-	PLPC_MESSAGE	Reply = NULL;
-	SM_PORT_MESSAGE	Request = {{0}};
-
-	DPRINT("SM: %s running\n",__FUNCTION__);
-
+	LPC_MAX_MESSAGE	Request = {{0}};
+    
 	while (TRUE)
 	{
-		DPRINT("SM: %s: waiting for message\n",__FUNCTION__);
-
-		Status = NtReplyWaitReceivePort(Port,
-						(PULONG) & Unknown,
-						Reply,
-						(PLPC_MESSAGE) & Request);
-		if (NT_SUCCESS(Status))
+		Status = NtListenPort (ListeningPort, & Request.Header);
+		if (!NT_SUCCESS(Status))
 		{
-			DPRINT("SM: %s: message received (type=%d)\n",
-				__FUNCTION__,
-				PORT_MESSAGE_TYPE(Request));
-
-			switch (Request.Header.MessageType)
-			{
-			case LPC_CONNECTION_REQUEST:
-				SmpHandleConnectionRequest (Port, &Request);
-				Reply = NULL;
-				break;
-			case LPC_DEBUG_EVENT:
-//				DbgSsHandleKmApiMsg (&Request, 0);
-				Reply = NULL;
-				break;
-			case LPC_PORT_CLOSED:
-			      Reply = NULL;
-			      break;
-			default:
-				if ((Request.ApiIndex) &&
-					(Request.ApiIndex < (sizeof SmApi / sizeof SmApi[0])))
-				{
-					Status = SmApi[Request.ApiIndex](&Request);
-				      	Reply = (PLPC_MESSAGE) & Request;
-				} else {
-					Request.Status = STATUS_NOT_IMPLEMENTED;
-					Reply = (PLPC_MESSAGE) & Request;
-				}
-			}
+			DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__, Status);
+			break;
 		}
+		Status = SmpHandleConnectionRequest ((PSM_PORT_MESSAGE) & Request);
+		if(!NT_SUCCESS(Status))
+		{
+			DPRINT1("SM: %s: SmpHandleConnectionRequest failed (Status=0x%08lx)\n",
+				__FUNCTION__, Status);
+			break;
+		}
 	}
+	/* Cleanup */
+	NtClose(ListeningPort);
+	/* DIE */
+	NtTerminateThread(NtCurrentThread(), Status);
 }
 
 
@@ -186,9 +267,9 @@
 NTSTATUS
 SmCreateApiPort(VOID)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING UnicodeString;
-  NTSTATUS Status;
+  OBJECT_ATTRIBUTES  ObjectAttributes = {0};
+  UNICODE_STRING     UnicodeString = {0};
+  NTSTATUS           Status = STATUS_SUCCESS;
 
   RtlRosInitUnicodeStringFromLiteral(&UnicodeString,
 		       L"\\SmApiPort");
@@ -207,8 +288,10 @@
     {
       return(Status);
     }
-
-  /* Create two threads for "\SmApiPort" */
+  /*
+   * Create one thread for the named LPC
+   * port \SmApiPort
+   */
   RtlCreateUserThread(NtCurrentProcess(),
 		      NULL,
 		      FALSE,
@@ -220,17 +303,6 @@
 		      NULL,
 		      NULL);
 
-  RtlCreateUserThread(NtCurrentProcess(),
-		      NULL,
-		      FALSE,
-		      0,
-		      NULL,
-		      NULL,
-		      (PTHREAD_START_ROUTINE)SmpApiThread,
-		      (PVOID)SmApiPort,
-		      NULL,
-		      NULL);
-
   return(Status);
 }
 

Added: trunk/reactos/subsys/smss/smapicomp.c
--- trunk/reactos/subsys/smss/smapicomp.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/smapicomp.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -0,0 +1,27 @@
+/* $Id: $
+ *
+ * smapicomp.c - SM_API_COMPLETE_SESSION
+ *
+ * Reactos Session Manager
+ *
+ */
+
+#include "smss.h"
+#include <rosrtl/string.h>
+
+#define NDEBUG
+#include <debug.h>
+
+
+/**********************************************************************
+ * SmCompSes/1							API
+ */
+SMAPI(SmCompSes)
+{
+	DPRINT("SM: %s called\n",__FUNCTION__);
+	Request->Status = STATUS_NOT_IMPLEMENTED;
+	return STATUS_SUCCESS;
+}
+
+
+/* EOF */

Added: trunk/reactos/subsys/smss/smapiexec.c
--- trunk/reactos/subsys/smss/smapiexec.c	2005-02-19 22:56:59 UTC (rev 13653)
+++ trunk/reactos/subsys/smss/smapiexec.c	2005-02-19 22:58:18 UTC (rev 13654)
@@ -0,0 +1,113 @@
+/* $Id: $
+ *
+ * smapiexec.c - SM_API_EXECUTE_PROGRAM
+ *
+ * Reactos Session Manager
+ *
+ */
+
+#include "smss.h"
+#include <rosrtl/string.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/**********************************************************************
+ * SmCreateUserProcess/5
+ *
+ */
+NTSTATUS STDCALL
+SmCreateUserProcess (LPWSTR ImagePath,
+		     LPWSTR CommandLine,
+		     BOOLEAN WaitForIt,
+		     PLARGE_INTEGER Timeout OPTIONAL,
+		     BOOLEAN TerminateIt,
+		     PRTL_PROCESS_INFO UserProcessInfo OPTIONAL
+		     )
+{
+	UNICODE_STRING			ImagePathString = {0};
+	UNICODE_STRING			CommandLineString = {0};
+	PRTL_USER_PROCESS_PARAMETERS	ProcessParameters = NULL;
+	RTL_PROCESS_INFO		ProcessInfo = {0};
+	PRTL_PROCESS_INFO		pProcessInfo = & ProcessInfo;
+	NTSTATUS			Status = STATUS_SUCCESS;
+
+
+	DPRINT("SM: %s called\n",__FUNCTION__);
+
+	RtlInitUnicodeString (& ImagePathString, ImagePath);
+	RtlInitUnicodeString (& CommandLineString, CommandLine);
+
+	RtlCreateProcessParameters(& ProcessParameters,
+				   & ImagePathString,
+				   NULL,
+				   NULL,
+				   & CommandLineString,
+				   SmSystemEnvironment,
+				   NULL,
+				   NULL,
+				   NULL,
+				   NULL);
+
+	if(NULL != UserProcessInfo)
+	{
+		/* Use caller provided storage */
+		pProcessInfo = UserProcessInfo;
+	}
+
+	Status = RtlCreateUserProcess (& ImagePathString,
+				       OBJ_CASE_INSENSITIVE,
[truncated at 1000 lines; 141 more skipped]