ea@reactos.com
- make SmExecuteProgram work
- implement SmCompleteSession (untested)
Modified: trunk/reactos/subsys/smss/client.c
Modified: trunk/reactos/subsys/smss/initss.c
Modified: trunk/reactos/subsys/smss/smapi.c
Modified: trunk/reactos/subsys/smss/smapicomp.c
Modified: 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-03-13 17:00:19 UTC (rev 14015)
+++ trunk/reactos/subsys/smss/client.c	2005-03-13 17:01:59 UTC (rev 14016)
@@ -42,40 +42,7 @@
 
 } 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
@@ -85,18 +52,48 @@
 	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
+ *	SmCompleteClientInitialization/1
  *
  * DESCRIPTION
+ * 	Lookup the subsystem server descriptor given the process handle
+ * 	of the subsystem server process.
+ */
+NTSTATUS STDCALL
+SmCompleteClientInitialization (HANDLE hProcess)
+{
+	NTSTATUS        Status = STATUS_SUCCESS;
+	PSM_CLIENT_DATA Client = NULL;
+
+	DPRINT("SM: %s called\n", __FUNCTION__);
+
+	RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+	if (SmpClientDirectory.Count > 0)
+	{
+		Client = SmpClientDirectory.Client;
+		while (NULL != Client)
+		{
+			if (hProcess == Client->ServerProcess)
+			{
+				Client->Initialized = TRUE;
+				break;
+			}
+			Client = Client->Next;
+		}
+		Status = STATUS_NOT_FOUND;
+	}
+	RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+	return Status;
+}
+
+/**********************************************************************
+ *	SmpLookupClient/1					PRIVATE
+ *
+ * DESCRIPTION
  * 	Lookup the subsystem server descriptor given its image ID.
  *
  * SIDE EFFECTS
@@ -148,7 +145,7 @@
 	 */
 	if (SmpLookupClient(ConnectData->Subsystem))
 	{
-		DPRINT("SMSS: %s: attempt to register again subsystem %d.\n",
+		DPRINT("SM: %s: attempt to register again subsystem %d.\n",
 			__FUNCTION__,
 			ConnectData->Subsystem);
 		return STATUS_UNSUCCESSFUL;

Modified: trunk/reactos/subsys/smss/initss.c
--- trunk/reactos/subsys/smss/initss.c	2005-03-13 17:00:19 UTC (rev 14015)
+++ trunk/reactos/subsys/smss/initss.c	2005-03-13 17:01:59 UTC (rev 14016)
@@ -53,7 +53,43 @@
  */
 
 /**********************************************************************
+ *	SmpRegisterSmss/0
+ *
+ * DESCRIPTION
+ *	Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
+ *	(programmatically). This also open hSmApiPort to be used
+ *	in loading required subsystems.
  */
+#if 0
+static NTSTATUS
+SmpRegisterSmss(VOID)
+{
+	NTSTATUS Status = STATUS_SUCCESS;
+	UNICODE_STRING SbApiPortName = {0,0,NULL};
+
+	DPRINT("SM: %s called\n",__FUNCTION__);
+	
+	Status = SmConnectApiPort(& SbApiPortName,
+				  (HANDLE) 0,
+				  IMAGE_SUBSYSTEM_NATIVE,
+				  & hSmApiPort);
+	if(!NT_SUCCESS(Status))
+	{
+		DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",
+			__FUNCTION__,Status);
+		return Status;
+	}
+	/*
+	 * Note that you don't need to call complete session
+	 * because connection handling code autocompletes
+	 * the client structure for IMAGE_SUBSYSTEM_NATIVE.
+	 */
+	return Status;
+}
+#endif
+
+/**********************************************************************
+ */
 NTSTATUS
 SmLoadSubsystems(VOID)
 {
@@ -65,7 +101,15 @@
 
 
 	DPRINT("SM: loading subsystems\n");
- 
+
+	/* SM self registers */
+#if 0
+	Status = SmpRegisterSmss();
+	if(!NT_SUCCESS(Status))
+	{
+		DPRINT1("SM: SM failed to self register: system is not secure!\n");
+	}
+#endif
 	/* Load Kmode subsystem (aka win32k.sys) */
 	Status = SmLookupSubsystem (L"Kmode",
 				    Data,
@@ -91,6 +135,13 @@
 		}
 	}
 	/* TODO: load Required subsystems (Debug Windows) */
+#if 0
+	Status = SmExecuteProgram(L"DEBUG");
+	if(!NT_SUCCESS(Status))
+	{
+		DPRINT1("SM: DBSS failed to initialize!\n");
+	}
+#endif
 	return Status;
 }
 

Modified: trunk/reactos/subsys/smss/smapi.c
--- trunk/reactos/subsys/smss/smapi.c	2005-03-13 17:00:19 UTC (rev 14015)
+++ trunk/reactos/subsys/smss/smapi.c	2005-03-13 17:01:59 UTC (rev 14016)
@@ -51,20 +51,22 @@
  * 	Entry point for the listener thread of LPC port "\SmApiPort".
  */
 VOID STDCALL
-SmpApiConnectedThread(PVOID dummy)
+SmpApiConnectedThread(PVOID pConnectedPort)
 {
 	NTSTATUS	Status = STATUS_SUCCESS;
 	PVOID		Unknown = NULL;
 	PLPC_MESSAGE	Reply = NULL;
 	SM_PORT_MESSAGE	Request = {{0}};
+	HANDLE          ConnectedPort = * (PHANDLE) pConnectedPort;
 
-	DPRINT("SM: %s running\n",__FUNCTION__);
+	DPRINT("SM: %s(%08lx) running\n", __FUNCTION__, pConnectedPort);
+	DPRINT("SM: %s(%08lx): ConnectedPort = %08lx\n",  __FUNCTION__, pConnectedPort, ConnectedPort);
 
 	while (TRUE)
 	{
 		DPRINT("SM: %s: waiting for message\n",__FUNCTION__);
 
-		Status = NtReplyWaitReceivePort(SmApiPort,
+		Status = NtReplyWaitReceivePort(ConnectedPort,
 						(PULONG) & Unknown,
 						Reply,
 						(PLPC_MESSAGE) & Request);
@@ -98,8 +100,13 @@
 					Reply = (PLPC_MESSAGE) & Request;
 				}
 			}
+		} else {
+			/* LPC failed */
+			break;
 		}
 	}
+	NtClose (ConnectedPort);
+	NtTerminateThread (NtCurrentThread(), Status);
 }
 
 /**********************************************************************
@@ -115,75 +122,91 @@
 NTSTATUS STDCALL
 SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
 {
-#if defined(__USE_NT_LPC__)
+	PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);
 	NTSTATUS         Status = STATUS_SUCCESS;
+	BOOL             Accept = FALSE;
 	PSM_CLIENT_DATA  ClientData = NULL;
+	HANDLE           hClientDataApiPort = (HANDLE) 0;
+	PHANDLE          ClientDataApiPort = & hClientDataApiPort;
+	HANDLE           hClientDataApiPortThread = (HANDLE) 0;
+	PHANDLE          ClientDataApiPortThread = & hClientDataApiPortThread;
 	PVOID            Context = NULL;
 	
-	DPRINT("SM: %s called\n",__FUNCTION__);
+	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)
+	if(sizeof (SM_CONNECT_DATA) == Request->Header.DataSize)
 	{
-		/* OK: the client is an environment subsystem
-		 * willing to manage a free image type.
-		 * Accept it.
-		 */
-		Status = NtAcceptConnectPort (& ClientData->ApiPort,
-					      Context,
-					      (PLPC_MESSAGE) Request,
-					      TRUE, //accept
-					      NULL,
-					      NULL);
-		if(NT_SUCCESS(Status))
+		if(IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->Subsystem)
 		{
-			Status = NtCompleteConnectPort(ClientData->ApiPort);
+			/*
+			 * This is not a call from an environment server
+			 * willing to register, but from any other process
+			 * that will use the SM API.
+			 */
+			DPRINT("SM: %s: req from NON subsys server process\n", __FUNCTION__);
+			ClientDataApiPort = & hClientDataApiPort;
+			ClientDataApiPortThread = & hClientDataApiPortThread;
+			Accept = TRUE;
+		} else {
+			DPRINT("SM: %s: req from subsys server process\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)
+			{
+				/* OK: the client is an environment subsystem
+				 * willing to manage a free image type.
+				 */
+				ClientDataApiPort = & ClientData->ApiPort;
+				ClientDataApiPortThread = & ClientData->ApiPortThread;
+				/*
+				 *  Reject GUIs: only odd subsystem IDs are
+				 *  allowed to register here.
+				 */
+				Accept = (1 == (ConnectData->Subsystem % 2));
+			}
 		}
-		return STATUS_SUCCESS;
-	} else {
-		/* Reject the subsystem */
-		Status = NtAcceptConnectPort (& ClientData->ApiPort,
-					      Context,
-					      (PLPC_MESSAGE) Request,
-					      FALSE, //reject
-					      NULL,
-					      NULL);
 	}
+#if defined(__USE_NT_LPC__)
+	Status = NtAcceptConnectPort (ClientDataApiPort,
+				      Context,
+				      (PLPC_MESSAGE) Request,
+				      Accept,
+				      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 (ClientDataApiPort,
+				      SmApiPort, // ROS LPC requires the listen port here
+				      Context,
+				      Accept,
+				      NULL,
+				      NULL);
+#endif
+	DPRINT("SM: %s: ClientDataPort=0x%08lx\n", __FUNCTION__, ClientDataApiPort);
+	DPRINT("SM: %s: *ClientDataPort=0x%08lx\n", __FUNCTION__, *ClientDataApiPort);
+	if(Accept)
 	{
-		Status = NtAcceptConnectPort (& ClientData->ApiPort,
-					      SmApiPort,
-					      NULL,
-					      TRUE, //accept
-					      NULL,
-					      NULL);
-		if (!NT_SUCCESS(Status))
+		if(!NT_SUCCESS(Status))
 		{
 			DPRINT1("SM: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
-					__FUNCTION__, Status);
+				__FUNCTION__, Status);
 			return Status;
 		} else {
-			Status = NtCompleteConnectPort(ClientData->ApiPort);
+			DPRINT("SM: %s: completing conn req\n", __FUNCTION__);
+			Status = NtCompleteConnectPort (*ClientDataApiPort);
 			if (!NT_SUCCESS(Status))
 			{
 				DPRINT1("SM: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
 					__FUNCTION__, Status);
 				return Status;
 			}
+#if !defined(__USE_NT_LPC__) /* ReactOS LPC */
+			DPRINT("SM: %s: server side comm port thread (ROS LPC)\n", __FUNCTION__);
 			Status = RtlCreateUserThread(NtCurrentProcess(),
 					     NULL,
 					     FALSE,
@@ -191,8 +214,8 @@
 					     NULL,
 					     NULL,
 					     (PTHREAD_START_ROUTINE) SmpApiConnectedThread,
-					     ClientData->ApiPort,
-					     & ClientData->ApiPortThread,
+					     ClientDataApiPort,
+					     ClientDataApiPortThread,
 					     NULL);
 			if (!NT_SUCCESS(Status))
 			{
@@ -200,18 +223,11 @@
 					__FUNCTION__, Status);
 				return Status;
 			}
+#endif
 		}
-		return STATUS_SUCCESS;
-	} else {
-		/* Reject the subsystem */
-		Status = NtAcceptConnectPort (& ClientData->ApiPort,
-					      SmApiPort,
-					      NULL,
-					      FALSE, //reject
-					      NULL,
-					      NULL);
+		Status = STATUS_SUCCESS;
 	}
-#endif /* defined __USE_NT_LPC__ */
+	DPRINT("SM: %s done\n", __FUNCTION__);
 	return Status;
 }
 

Modified: trunk/reactos/subsys/smss/smapicomp.c
--- trunk/reactos/subsys/smss/smapicomp.c	2005-03-13 17:00:19 UTC (rev 14015)
+++ trunk/reactos/subsys/smss/smapicomp.c	2005-03-13 17:01:59 UTC (rev 14016)
@@ -4,10 +4,26 @@
  *
  * Reactos Session Manager
  *
+ * --------------------------------------------------------------------
+ *
+ * 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.  
+ *
+ * --------------------------------------------------------------------
  */
-
 #include "smss.h"
-#include <rosrtl/string.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -18,9 +34,19 @@
  */
 SMAPI(SmCompSes)
 {
-	DPRINT("SM: %s called\n",__FUNCTION__);
-	Request->Status = STATUS_NOT_IMPLEMENTED;
-	return STATUS_SUCCESS;
+	NTSTATUS Status = STATUS_SUCCESS;
+
+	DPRINT("SM: %s called from [%lx|%lx]\n",
+		__FUNCTION__,
+		Request->ClientId.UniqueProcessId,
+		Request->ClientId.UniqueThreadId);
+	
+	Status = SmCompleteClientInitialization (Request->Header.ClientId.UniqueProcess);
+	if(!NT_SUCCESS(Status))
+	{
+		Request->Status = STATUS_UNSUCCESSFUL;
+	}
+	return Status;
 }
 
 

Modified: trunk/reactos/subsys/smss/smapiexec.c
--- trunk/reactos/subsys/smss/smapiexec.c	2005-03-13 17:00:19 UTC (rev 14015)
+++ trunk/reactos/subsys/smss/smapiexec.c	2005-03-13 17:01:59 UTC (rev 14016)
@@ -285,18 +285,23 @@
 		}
 		else
 		{
-			WCHAR ImagePath [1024] = {0};
-			ULONG ImagePathLength = sizeof ImagePath;
-			ULONG ImagePathType = REG_EXPAND_SZ;
+			WCHAR Data [MAX_PATH + 1] = {0};
+			ULONG DataLength = sizeof Data;
+			ULONG DataType = REG_EXPAND_SZ;
 
 			/* Lookup Name in the registry */
 			Status = SmLookupSubsystem (Name,
-						    ImagePath,
-						    & ImagePathLength,
-						    & ImagePathType,
+						    Data,
+						    & DataLength,
+						    & DataType,
 						    TRUE); /* expand */
 			if(NT_SUCCESS(Status))
 			{
+				WCHAR ImagePath [MAX_PATH + 1] = {0};
+
+				wcscpy (ImagePath, L"\\??\\");
+				wcscat (ImagePath, Data);
+			
 				/* Create native process */
 				Request->Status = SmCreateUserProcess(ImagePath,
 								      L"", /* FIXME */

Modified: trunk/reactos/subsys/smss/smss.c
--- trunk/reactos/subsys/smss/smss.c	2005-03-13 17:00:19 UTC (rev 14015)
+++ trunk/reactos/subsys/smss/smss.c	2005-03-13 17:01:59 UTC (rev 14016)
@@ -40,7 +40,6 @@
   NTSTATUS Status;
   PROCESS_BASIC_INFORMATION PBI = {0};
   
-  DisplayString(L"SMSS\n");
   PrintString("ReactOS Session Manager %s (Build %s)\n",
 	     KERNEL_RELEASE_STR,
 	     KERNEL_VERSION_BUILD_STR);

Modified: trunk/reactos/subsys/smss/smss.h
--- trunk/reactos/subsys/smss/smss.h	2005-03-13 17:00:19 UTC (rev 14015)
+++ trunk/reactos/subsys/smss/smss.h	2005-03-13 17:01:59 UTC (rev 14016)
@@ -91,9 +91,9 @@
 	
 } SM_CLIENT_DATA, *PSM_CLIENT_DATA;
 NTSTATUS SmInitializeClientManagement(VOID);
-NTSTATUS SmpRegisterSmss(VOID);
 NTSTATUS STDCALL SmCreateClient(PSM_PORT_MESSAGE,PSM_CLIENT_DATA*);
 NTSTATUS STDCALL SmDestroyClient(ULONG);
+NTSTATUS STDCALL SmCompleteClientInitialization (HANDLE hProcess);
 
 /* debug.c */
 extern HANDLE DbgSsApiPort;