SM: init system reading the registry
CSR: register with SM for IMAGE_SUBSYSTEM_WINDOWS_CUI
Modified: trunk/reactos/subsys/csrss/api/wapi.c
Modified: trunk/reactos/subsys/csrss/csrss.c
Modified: trunk/reactos/subsys/csrss/include/api.h
Modified: trunk/reactos/subsys/csrss/init.c
Modified: trunk/reactos/subsys/csrss/win32csr/conio.c
Modified: trunk/reactos/subsys/smss/client.c
Modified: trunk/reactos/subsys/smss/init.c
Modified: trunk/reactos/subsys/smss/initss.c
Modified: trunk/reactos/subsys/smss/makefile
Modified: trunk/reactos/subsys/smss/smapi.c
Modified: trunk/reactos/subsys/smss/smapiexec.c
Added: trunk/reactos/subsys/smss/smapiquery.c
Modified: trunk/reactos/subsys/smss/smss.c
Modified: trunk/reactos/subsys/smss/smss.h

Modified: trunk/reactos/subsys/csrss/api/wapi.c
--- trunk/reactos/subsys/csrss/api/wapi.c	2005-03-20 22:09:14 UTC (rev 14243)
+++ trunk/reactos/subsys/csrss/api/wapi.c	2005-03-20 22:55:05 UTC (rev 14244)
@@ -10,16 +10,21 @@
 
 /* INCLUDES ******************************************************************/
 
+#define NTOS_MODE_USER
+#include <ntos.h>
 #include <csrss/csrss.h>
 #include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
+
+
+
+#define NDEBUG
 #include <debug.h>
 
 #include "api.h"
 
 /* GLOBALS *******************************************************************/
 
-HANDLE CsrssApiHeap;
+HANDLE CsrssApiHeap = (HANDLE) 0;
 
 static unsigned ApiDefinitionsCount = 0;
 static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
@@ -33,6 +38,8 @@
   PCSRSS_API_DEFINITION Scan;
   PCSRSS_API_DEFINITION New;
 
+	DPRINT("CSR: %s called", __FUNCTION__);
+
   NewCount = 0;
   for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
     {
@@ -107,6 +114,8 @@
   PCSRSS_PROCESS_DATA ProcessData;
   PCSRSS_API_REPLY Reply;
    
+	DPRINT("CSR: %s called", __FUNCTION__);
+
   Reply = NULL;
    
   for (;;)
@@ -153,34 +162,37 @@
  * 	Handle connection requests from clients to the port
  * 	"\Windows\ApiPort".
  */
-void STDCALL
+DWORD STDCALL
 ServerApiPortThread (PVOID PortHandle)
 {
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
    LPC_MAX_MESSAGE Request;
-   HANDLE ServerPort;
-   HANDLE ServerThread;
-   PCSRSS_PROCESS_DATA ProcessData;
+   HANDLE hApiListenPort = * (PHANDLE) PortHandle;
+   HANDLE ServerPort = (HANDLE) 0;
+   HANDLE ServerThread = (HANDLE) 0;
+   PCSRSS_PROCESS_DATA ProcessData = NULL;
    
    CsrInitProcessData();
    
+	DPRINT("CSR: %s called", __FUNCTION__);
+
    for (;;)
      {
         LPC_SECTION_READ LpcRead;
         ServerPort = NULL;
 
-	Status = NtListenPort(PortHandle, &Request.Header);
+	Status = NtListenPort (hApiListenPort, & Request.Header);
 	if (!NT_SUCCESS(Status))
 	  {
 	     DPRINT1("CSR: NtListenPort() failed\n");
 	     break;
 	  }
-	Status = NtAcceptConnectPort(&ServerPort,
-				     PortHandle,
+	Status = NtAcceptConnectPort(& ServerPort,
+				     hApiListenPort,
 				     NULL,
 				     TRUE,
 				     0,
-				     &LpcRead);
+				     & LpcRead);
 	if (!NT_SUCCESS(Status))
 	  {
 	     DPRINT1("CSR: NtAcceptConnectPort() failed\n");
@@ -215,7 +227,7 @@
 				     NULL,
 				     (PTHREAD_START_ROUTINE)ClientConnectionThread,
 				     ServerPort,
-				     &ServerThread,
+				     & ServerThread,
 				     NULL);
 	if (!NT_SUCCESS(Status))
 	  {
@@ -230,6 +242,7 @@
      }
    NtClose(PortHandle);
    NtTerminateThread(NtCurrentThread(), Status);
+   return 0;
 }
 
 /**********************************************************************
@@ -238,45 +251,88 @@
  *
  * DESCRIPTION
  * 	Handle connection requests from SM to the port
- * 	"\Windows\SbApiPort".
+ * 	"\Windows\SbApiPort". We will accept only one
+ * 	connection request (from the SM).
  */
-VOID STDCALL
+DWORD STDCALL
 ServerSbApiPortThread (PVOID PortHandle)
 {
-	HANDLE          hSbApiPortListen = (HANDLE) PortHandle;
+	HANDLE          hSbApiPortListen = * (PHANDLE) PortHandle;
 	HANDLE          hConnectedPort = (HANDLE) 0;
 	LPC_MAX_MESSAGE Request = {{0}};
+	PVOID           Context = NULL;
 	NTSTATUS        Status = STATUS_SUCCESS;
 
-	while (TRUE)
+	DPRINT("CSR: %s called\n", __FUNCTION__);
+
+	Status = NtListenPort (hSbApiPortListen, & Request.Header);
+	if (!NT_SUCCESS(Status))
 	{
-		Status = NtListenPort (hSbApiPortListen, & Request.Header);
-		if (!NT_SUCCESS(Status))
-		{
-			DPRINT1("CSR: %s: NtListenPort(SB) failed\n", __FUNCTION__);
-			break;
-		}
+		DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
+			__FUNCTION__, Status);
+	} else {
+DPRINT("-- 1\n");
 		Status = NtAcceptConnectPort (& hConnectedPort,
 						hSbApiPortListen,
-	   					NULL,
-	   					TRUE,
-	   					NULL,
+   						NULL,
+   						TRUE,
+   						NULL,
 	   					NULL);
 		if(!NT_SUCCESS(Status))
 		{
-			DPRINT1("CSR: %s: NtAcceptConnectPort() failed\n", __FUNCTION__);
-			break;
+			DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
+				__FUNCTION__, Status);
+		} else {
+DPRINT("-- 2\n");
+			Status = NtCompleteConnectPort (hConnectedPort);
+			if(!NT_SUCCESS(Status))
+			{
+				DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
+					__FUNCTION__, Status);
+			} else {
+DPRINT("-- 3\n");
+				PLPC_MESSAGE Reply = NULL;
+				/* 
+				 * Tell the init thread the SM gave the
+				 * green light for boostrapping.
+				 */
+				Status = NtSetEvent (hBootstrapOk, NULL);
+				if(!NT_SUCCESS(Status))
+				{
+					DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
+						__FUNCTION__, Status);
+				}
+				/* Wait for messages from the SM */
+DPRINT("-- 4\n");
+				while (TRUE)
+				{
+					Status = NtReplyWaitReceivePort(hConnectedPort,
+                                      					Context,
+									Reply,
+									& Request.Header);
+					if(!NT_SUCCESS(Status))
+					{
+						DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
+							__FUNCTION__, Status);
+						break;
+					}
+					switch (Request.Header.MessageType)//fix .h PORT_MESSAGE_TYPE(Request))
+					{
+						/* TODO */
+					default:
+						DPRINT1("CSR: %s received message (type=%d)\n",
+							__FUNCTION__, Request.Header.MessageType);
+					}
+DPRINT("-- 5\n");
+				}
+			}
 		}
-		Status = NtCompleteConnectPort (hConnectedPort);
-		if(!NT_SUCCESS(Status))
-		{
-			DPRINT1("CSR: %s: NtCompleteConnectPort() failed\n", __FUNCTION__);
-			break;
-		}
-		/* TODO: create thread for the connected port */
 	}
+	DPRINT1("CSR: %s: terminating!\n", __FUNCTION__);
+	if(hConnectedPort) NtClose (hConnectedPort);
 	NtClose (hSbApiPortListen);
 	NtTerminateThread (NtCurrentThread(), Status);
+	return 0;
 }
 
 /* EOF */

Modified: trunk/reactos/subsys/csrss/csrss.c
--- trunk/reactos/subsys/csrss/csrss.c	2005-03-20 22:09:14 UTC (rev 14243)
+++ trunk/reactos/subsys/csrss/csrss.c	2005-03-20 22:55:05 UTC (rev 14244)
@@ -35,6 +35,7 @@
 #include <ntdll/rtl.h>
 #include <csrss/csrss.h>
 #include <rosrtl/string.h>
+#include <reactos/buildno.h>
 
 #include "api.h"
 
@@ -145,78 +146,37 @@
 }
 
 
-/**********************************************************************
- * NAME							PRIVATE
- * 	CsrpOpenSmInitDoneEvent/0
- */
-static NTSTATUS STDCALL
-CsrpOpenSmInitDoneEvent (PHANDLE CsrssInitEvent)
-{
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   UNICODE_STRING    EventName;
-
-   DPRINT("CSR: %s called\n", __FUNCTION__);
-
-   RtlInitUnicodeString(& EventName,
-			L"\\CsrssInitDone");
-   InitializeObjectAttributes (& ObjectAttributes,
-				& EventName,
-				EVENT_ALL_ACCESS,
-				0,
-				NULL);
-   return NtOpenEvent (CsrssInitEvent,
-			EVENT_ALL_ACCESS,
-			& ObjectAttributes);
-}
-
 /* Native process' entry point */
 
 VOID STDCALL NtProcessStartup(PPEB Peb)
 {
    PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters = NULL;
    COMMAND_LINE_ARGUMENT        CmdLineArg = {0};
-   HANDLE                       CsrssInitEvent = (HANDLE) 0;
    NTSTATUS                     Status = STATUS_SUCCESS;
 
-   DPRINT("CSR: %s\n", __FUNCTION__);
+   PrintString("ReactOS Client/Server Run-Time %s (Build %s)\n",
+	     KERNEL_RELEASE_STR,
+	     KERNEL_VERSION_BUILD_STR);
 
    RtlProcessParameters = RtlNormalizeProcessParams (Peb->ProcessParameters);
 
    /*==================================================================
-    * Parse the command line.
+    * Parse the command line: TODO actually parse the cl, because
+    * it is required to load hosted server DLLs.
     *================================================================*/
    Status = CsrpParseCommandLine (Peb->ProcessHeap,
 				  RtlProcessParameters,
 				  & CmdLineArg);
    if(STATUS_SUCCESS != Status)
    {
-	   DbgPrint("CSR: CsrpParseCommandLine failed (Status=0x%08lx)\n",
-		Status);
+	   DPRINT1("CSR: %s: CsrpParseCommandLine failed (Status=0x%08lx)\n",
+		__FUNCTION__, Status);
    }
-   /*
-    * Open the SM notification event to notify we are OK after
-    * subsystem server initialization.
-    */
-   Status = CsrpOpenSmInitDoneEvent(& CsrssInitEvent);
-   if (!NT_SUCCESS(Status))
-     {
-	DbgPrint("CSR: CsrpOpenSmInitDoneEvent failed (Status=0x%08lx)\n",
-			Status);
-     }
    /*==================================================================
     *	Initialize the Win32 environment subsystem server.
     *================================================================*/
    if (CsrServerInitialization (CmdLineArg.Count, CmdLineArg.Vector) == TRUE)
      {
-	/*=============================================================
-	 * Tell SM we are up and safe. If we fail to notify SM, it will
-	 * die and the kernel will bugcheck with
-	 * SESSION5_INITIALIZATION_FAILED.
-	 * TODO: this won't be necessary, because CSR will call SM
-	 * API SM_SESSION_COMPLETE.
-	 *===========================================================*/
-	NtSetEvent (CsrssInitEvent, NULL);
-
 	CsrpFreeCommandLine (Peb->ProcessHeap, & CmdLineArg);	
 	/*
 	 * Terminate the current thread only.

Modified: trunk/reactos/subsys/csrss/include/api.h
--- trunk/reactos/subsys/csrss/include/api.h	2005-03-20 22:09:14 UTC (rev 14243)
+++ trunk/reactos/subsys/csrss/include/api.h	2005-03-20 22:55:05 UTC (rev 14244)
@@ -82,6 +82,9 @@
 PCSRSS_API_REQUEST Request,\
 PCSRSS_API_REPLY Reply)
 
+/* init.c */
+extern HANDLE hBootstrapOk;
+
 /* api/process.c */
 CSR_API(CsrConnectProcess);
 CSR_API(CsrCreateProcess);
@@ -96,9 +99,9 @@
 VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
                                 PCSRSS_API_REQUEST Request,
                                 PCSRSS_API_REPLY Reply);
-VOID STDCALL ServerApiPortThread (PVOID PortHandle);
-VOID STDCALL ServerSbApiPortThread (PVOID PortHandle);
-VOID Console_Api( DWORD Ignored );
+DWORD STDCALL ServerApiPortThread (PVOID PortHandle);
+DWORD STDCALL ServerSbApiPortThread (PVOID PortHandle);
+DWORD STDCALL Console_Api( PVOID unused );
 
 extern HANDLE CsrssApiHeap;
 

Modified: trunk/reactos/subsys/csrss/init.c
--- trunk/reactos/subsys/csrss/init.c	2005-03-20 22:09:14 UTC (rev 14243)
+++ trunk/reactos/subsys/csrss/init.c	2005-03-20 22:55:05 UTC (rev 14244)
@@ -27,10 +27,9 @@
 
 /* GLOBALS ******************************************************************/
 
-HANDLE CsrInitEvent = INVALID_HANDLE_VALUE;
-HANDLE CsrHeap = INVALID_HANDLE_VALUE;
+HANDLE CsrHeap = (HANDLE) 0;
 
-HANDLE CsrObjectDirectory = INVALID_HANDLE_VALUE;
+HANDLE CsrObjectDirectory = (HANDLE) 0;
 
 UNICODE_STRING CsrDirectoryName;
 
@@ -39,11 +38,24 @@
 static unsigned InitCompleteProcCount;
 static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
 
+HANDLE hSbApiPort = (HANDLE) 0;
+
+HANDLE hBootstrapOk = (HANDLE) 0;
+
+HANDLE hSmApiPort = (HANDLE) 0;
+
+HANDLE hApiPort = (HANDLE) 0;
+
+/**********************************************************************
+ * CsrpAddInitCompleteProc/1
+ */
 static NTSTATUS FASTCALL
-AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
+CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
 {
   CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
   NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
                              (InitCompleteProcCount + 1)
                              * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
@@ -64,12 +76,17 @@
   return STATUS_SUCCESS;
 }
 
+/**********************************************************************
+ * CallInitComplete/0
+ */
 static BOOL FASTCALL
 CallInitComplete(void)
 {
   BOOL Ok;
   unsigned i;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
   Ok = TRUE;
   if (0 != InitCompleteProcCount)
     {
@@ -86,8 +103,11 @@
 ULONG
 InitializeVideoAddressSpace(VOID);
 
+/**********************************************************************
+ * CsrpParseCommandLine/2
+ */
 static NTSTATUS
-CsrParseCommandLine (
+CsrpParseCommandLine (
 	ULONG ArgumentCount,
 	PWSTR *ArgumentArray
 	)
@@ -95,7 +115,9 @@
    NTSTATUS Status;
    OBJECT_ATTRIBUTES Attributes;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
 
+
    /*   DbgPrint ("Arguments: %ld\n", ArgumentCount);
    for (i = 0; i < ArgumentCount; i++)
      {
@@ -114,22 +136,29 @@
 	                            NULL);
 
 	Status = NtCreateDirectoryObject(&CsrObjectDirectory,
-	                                 0xF000F,
+	                                 0xF000F, /* ea:??? */
 	                                 &Attributes);
 
 	return Status;
 }
 
-
-static VOID
-CsrInitVideo(VOID)
+/**********************************************************************
+ * CsrpInitVideo/0
+ *
+ * TODO: we need a virtual device for sessions other than
+ * TODO: the console one
+ */
+static NTSTATUS
+CsrpInitVideo (ULONG argc, PWSTR* argv)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING DeviceName;
   IO_STATUS_BLOCK Iosb;
-  HANDLE VideoHandle;
-  NTSTATUS Status;
+  HANDLE VideoHandle = (HANDLE) 0;
+  NTSTATUS Status = STATUS_SUCCESS;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
   InitializeVideoAddressSpace();
 
   RtlRosInitUnicodeStringFromLiteral(&DeviceName, L"\\??\\DISPLAY1");
@@ -148,10 +177,23 @@
     {
       NtClose(VideoHandle);
     }
+  return Status;
 }
 
-static NTSTATUS FASTCALL
-InitWin32Csr()
+/**********************************************************************
+ * CsrpInitWin32Csr/0
+ *
+ * TODO: this function should be turned more general to load an
+ * TODO: hosted server DLL as received from the command line;
+ * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
+ * TODO:               ^method   ^dll   ^api                       ^sid
+ * TODO:
+ * TODO: CsrpHostServerDll (LPWSTR DllName,
+ * TODO:                    LPWSTR ApiName,
+ * TODO:                    DWORD  ServerId)
+ */
+static NTSTATUS
+CsrpInitWin32Csr (ULONG argc, PWSTR* argv)
 {
   NTSTATUS Status;
   UNICODE_STRING DllName;
@@ -163,6 +205,8 @@
   PCSRSS_OBJECT_DEFINITION ObjectDefinitions;
   CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
   RtlInitUnicodeString(&DllName, L"win32csr.dll");
   Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst);
   if (! NT_SUCCESS(Status))
@@ -196,7 +240,7 @@
     }
   if (NULL != InitCompleteProc)
     {
-      Status = AddInitCompleteProc(InitCompleteProc);
+      Status = CsrpAddInitCompleteProc(InitCompleteProc);
     }
 
   return Status;
@@ -219,157 +263,292 @@
     { 0, 0, 0, NULL }
   };
 
+static NTSTATUS STDCALL
+CsrpCreateListenPort (IN     LPWSTR  Name,
+		      IN OUT PHANDLE Port,
+		      IN     PTHREAD_START_ROUTINE ListenThread)
+{
+	NTSTATUS           Status = STATUS_SUCCESS;
+	OBJECT_ATTRIBUTES  PortAttributes;
+	UNICODE_STRING     PortName;
+
+	DPRINT("CSR: %s called\n", __FUNCTION__);
+
+	RtlInitUnicodeString (& PortName, Name);
+	InitializeObjectAttributes (& PortAttributes,
+				    & PortName,
+				    0,
+				    NULL,
+				    NULL);
+	Status = NtCreatePort ( Port,
+				& PortAttributes,
+				260, /* TODO: make caller set it*/
+				328, /* TODO: make caller set it*/
+				0); /* TODO: make caller set it*/
+	if(!NT_SUCCESS(Status))
+	{
+		DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
+			__FUNCTION__, Status);
+		return Status;
+	}
+	Status = RtlCreateUserThread(NtCurrentProcess(),
+                               NULL,
+                               FALSE,
+                               0,
+                               NULL,
+                               NULL,
+                               (PTHREAD_START_ROUTINE) ListenThread,
+                               Port,
+                               NULL,
+                               NULL);
+	return Status;
+}
+
+/* === INIT ROUTINES === */
+
 /**********************************************************************
- * NAME
- * 	CsrpRegisterSubsystem/0
- *
- * DESCRIPTION
- * 	Register CSRSS in the SM to manage IMAGE_SUBSYSTEM_WINDOWS_CUI 
- * 	processes (environment subsystem server).
- *
- * RETURN VALUE
- * 	STATUS_SUCCESS on success.
+ * CsrpCreateCallbackPort/0
  */
-static NTSTATUS FASTCALL
-CsrpRegisterSubsystem(PHANDLE hSmApiPort)
+static NTSTATUS
+CsrpCreateHeap (ULONG argc, PWSTR* argv)
 {
-	NTSTATUS Status = STATUS_SUCCESS;
-	UNICODE_STRING SbApiPortName;
+	DPRINT("CSR: %s called\n", __FUNCTION__);
 
-	RtlInitUnicodeString (& SbApiPortName, L"\\Windows\\SbApiPort");
-	Status = SmConnectApiPort (& SbApiPortName,
-				   (HANDLE)-1, //unused
+	CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
+        	                       NULL,
+                	               65536,
+                        	       65536,
+	                               NULL,
+        	                       NULL);
+	if (CsrssApiHeap == NULL)
+	{
+		return STATUS_UNSUCCESSFUL;
+	}
+	return STATUS_SUCCESS;
+}
+
+/**********************************************************************
+ * CsrpCreateCallbackPort/0
+ */
+static NTSTATUS
+CsrpCreateCallbackPort (ULONG argc, PWSTR* argv)
+{
+	DPRINT("CSR: %s called\n", __FUNCTION__);
+
+	return CsrpCreateListenPort (L"\\Windows\\SbApiPort",
+				     & hSbApiPort,
+				     ServerSbApiPortThread);
+}
+
+/**********************************************************************
+ * CsrpRegisterSubsystem/2
+ */
+static NTSTATUS
+CsrpRegisterSubsystem (ULONG argc, PWSTR* argv)
+{
+	NTSTATUS           Status = STATUS_SUCCESS;
+	OBJECT_ATTRIBUTES  BootstrapOkAttributes;
+	UNICODE_STRING     Name;
+
+	DPRINT("CSR: %s called\n", __FUNCTION__);
+
+	/*
+	 * Create the event object the callback port
+	 * thread will signal *if* the SM will
+	 * authorize us to bootstrap.
+	 */
+	RtlInitUnicodeString (& Name, L"\\CsrssBooting");
+	InitializeObjectAttributes(& BootstrapOkAttributes,
+				   & Name,
+				   0, NULL, NULL);
+	Status = NtCreateEvent (& hBootstrapOk,
+				EVENT_ALL_ACCESS,
+				& BootstrapOkAttributes,
+				SynchronizationEvent,
+				FALSE);
+	if(!NT_SUCCESS(Status))
+	{
+		DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
+			__FUNCTION__, Status);
+		return Status;
+	}
+	/*
+	 * Let's tell the SM a new environment
+	 * subsystem server is in the system.
+	 */
+	RtlInitUnicodeString (& Name, L"\\Windows\\SbApiPort");
+	DPRINT("CSR: %s: registering with SM for\n  IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__);
+	Status = SmConnectApiPort (& Name,
+				   hSbApiPort,
 				   IMAGE_SUBSYSTEM_WINDOWS_CUI,
-				   hSmApiPort);
+				   & hSmApiPort);
 	if(!NT_SUCCESS(Status))
 	{
-		DPRINT("CSR: unable to connect to the SM (Status=0x%lx)\n", Status);
+		DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
+			__FUNCTION__, Status);
+		NtClose (hBootstrapOk);
 		return Status;
 	}
-	DisplayString(L"CSR: registered with SM\n");
+	/*
+	 *  Wait for SM to reply OK... If the SM
+	 *  won't answer, we hang here forever!
+	 */
+	DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__);
+	Status = NtWaitForSingleObject (hBootstrapOk,
+					FALSE,
+					NULL);
+	NtClose (hBootstrapOk);
 	return Status;	
 }
 
+/**********************************************************************
+ * CsrpCreateApiPort/0
+ */
+static NTSTATUS
+CsrpCreateApiPort (ULONG argc, PWSTR* argv)
+{
+	DPRINT("CSR: %s called\n", __FUNCTION__);
 
+	return CsrpCreateListenPort (L"\\Windows\\ApiPort",
+				     & hApiPort,
+				     ServerApiPortThread);
+}
+
 /**********************************************************************
+ * CsrpApiRegisterDef/0
+ */
+static NTSTATUS
+CsrpApiRegisterDef (ULONG argc, PWSTR* argv)
+{
+	return CsrApiRegisterDefinitions(NativeDefinitions);
+}
+
+/**********************************************************************
+ * CsrpCCTS/2
+ */
+static NTSTATUS
+CsrpCCTS (ULONG argc, PWSTR* argv)
+{
+	return CsrClientConnectToServer();
+}
+
+/**********************************************************************
+ * CsrpRunWinlogon/0
+ *
+ * Start the logon process (winlogon.exe).
+ *
+ * TODO: this should be moved in CsrpCreateSession/x (one per session)
+ * TODO: in its own desktop (one logon desktop per winstation).
+ */
+static NTSTATUS
+CsrpRunWinlogon (ULONG argc, PWSTR* argv)
+{
+	NTSTATUS                      Status = STATUS_SUCCESS;
+	UNICODE_STRING                ImagePath;
+	UNICODE_STRING                CommandLine;
+	PRTL_USER_PROCESS_PARAMETERS  ProcessParameters = NULL;
+	RTL_PROCESS_INFO              ProcessInfo;
+
+
+	DPRINT("CSR: %s called\n", __FUNCTION__);
+
+	/* initialize the process parameters */
+	RtlInitUnicodeString (& ImagePath, L"\\SystemRoot\\system32\\winlogon.exe");
+	RtlInitUnicodeString (& CommandLine, L"");
+	RtlCreateProcessParameters(& ProcessParameters,
+				   & ImagePath,
+				   NULL,
+				   NULL,
+				   & CommandLine,
+				   NULL,
+				   NULL,
+				   NULL,
+				   NULL,
+				   NULL);
+	/* Create the winlogon process */
+	Status = RtlCreateUserProcess (& ImagePath,
+				       OBJ_CASE_INSENSITIVE,
+				       ProcessParameters,
+				       NULL,
+				       NULL,
+				       NULL,
+				       FALSE,
+				       NULL,
+				       NULL,
+				       & ProcessInfo);
+	/* Cleanup */
+	RtlDestroyProcessParameters (ProcessParameters);
+	if (!NT_SUCCESS(Status))
+	{
+		DPRINT("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
+				__FUNCTION__, Status);
+	}
+	return Status;
+}
+
+
+
+typedef NTSTATUS (* CSR_INIT_ROUTINE)(ULONG, PWSTR*);
+
+struct {
+	BOOL Required;
+	CSR_INIT_ROUTINE EntryPoint;
+	PCHAR ErrorMessage;
+} InitRoutine [] = {
+	{TRUE, CsrpCreateCallbackPort, "create the callback port \\Windows\\SbApiPort"},
+	{TRUE, CsrpRegisterSubsystem,  "register with SM"},
+	{TRUE, CsrpCreateHeap,         "create the CSR heap"},
+	{TRUE, CsrpCreateApiPort,      "create the api port \\Windows\\ApiPort"},
+	{TRUE, CsrpParseCommandLine,   "parse the command line"},
+	{TRUE, CsrpInitVideo,          "initialize video"},
+	{TRUE, CsrpApiRegisterDef,     "initialize api definitions"},
+	{TRUE, CsrpCCTS,               "connect client to server"},
+	{TRUE, CsrpInitWin32Csr,       "load usermode dll"},
+	{TRUE, CsrpRunWinlogon,        "run WinLogon"},
+};
+
+/**********************************************************************
  * NAME
  * 	CsrServerInitialization
  *
  * DESCRIPTION
- * 	Create a directory object (\windows) and a named LPC port
- * 	(\windows\ApiPort)
+ * 	Initialize the Win32 environment subsystem server.
  *
  * RETURN VALUE
  * 	TRUE: Initialization OK; otherwise FALSE.
  */
-BOOL
-STDCALL
+BOOL STDCALL
 CsrServerInitialization (
 	ULONG ArgumentCount,
 	PWSTR *ArgumentArray
 	)
 {
-  NTSTATUS Status;
-  HANDLE hSmApiPort = (HANDLE) 0;
-  OBJECT_ATTRIBUTES ObAttributes;
-  UNICODE_STRING PortName;
-  HANDLE ApiPortHandle;
-//  HANDLE hSbApiPort = (HANDLE) 0;
+	INT       i = 0;
+	NTSTATUS  Status = STATUS_SUCCESS;
 
-DisplayString(L"CSR: CsrServerInitialization\n");
+	DPRINT("CSR: %s called\n", __FUNCTION__);
 
-  Status = CsrpRegisterSubsystem(& hSmApiPort);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to register subsystem (Status: %x)\n", Status);
-      return FALSE;
-    }
-
-  Status = CsrParseCommandLine (ArgumentCount, ArgumentArray);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to parse the command line (Status: %x)\n", Status);
-      return FALSE;
-    }
-
-  CsrInitVideo();
-
-  CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
-                               NULL,
-                               65536,
-                               65536,
-                               NULL,
-                               NULL);
-  if (CsrssApiHeap == NULL)
-    {
-      DPRINT1("CSR: Failed to create private heap, aborting\n");
-      return FALSE;
-    }
-
-  Status = CsrApiRegisterDefinitions(NativeDefinitions);
-  if (! NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-
-  /* NEW NAMED PORT: \Windows\ApiPort */
-  RtlRosInitUnicodeStringFromLiteral(&PortName, L"\\Windows\\ApiPort");
-  InitializeObjectAttributes(&ObAttributes,
-                             &PortName,
-                             0,
-                             NULL,
-                             NULL);
-  Status = NtCreatePort(&ApiPortHandle,
-                        &ObAttributes,
-                        260,
-                        328,
-                        0);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to create \\Windows\\ApiPort (Status %x)\n", Status);
-      return FALSE;
-    }
-  Status = RtlCreateUserThread(NtCurrentProcess(),
-                               NULL,
-                               FALSE,
-                               0,
-                               NULL,
-                               NULL,
-                               (PTHREAD_START_ROUTINE)ServerApiPortThread,
-                               ApiPortHandle,
-                               NULL,
-                               NULL);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to create server thread\n");
-      NtClose(ApiPortHandle);
-      return FALSE;
-    }
-
-  /* TODO: create \Windows\SbApiPort */
-  
-  Status = CsrClientConnectToServer();
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("CsrClientConnectToServer() failed (Status %x)\n", Status);
-      return FALSE;
-    }
-  Status = InitWin32Csr();
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to load usermode dll (Status %x)\n", Status);
-      return FALSE;
-    }
-
-  if (CallInitComplete())
-  {
-#if 0
-	  Status = SmCompleteSession (hSmApiPort,hSbApiPort,ApiPortHandle);
-#endif
-	  NtClose (hSmApiPort);
-	  return TRUE;
-  }
-  return FALSE;
+	for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
+	{
+		Status = InitRoutine[i].EntryPoint(ArgumentCount,ArgumentArray);
+		if(!NT_SUCCESS(Status))
+		{
+			DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n", 
+				__FUNCTION__,
+				InitRoutine[i].ErrorMessage,
+				Status);
+			if (InitRoutine[i].Required)
+			{
+				return FALSE;
+			}
+		}
+	}
+	if (CallInitComplete())
+	{
+		Status = SmCompleteSession (hSmApiPort,hSbApiPort,hApiPort);
+		return TRUE;
+	}
+	return FALSE;
 }
 
 /* EOF */

Modified: trunk/reactos/subsys/csrss/win32csr/conio.c
--- trunk/reactos/subsys/csrss/win32csr/conio.c	2005-03-20 22:09:14 UTC (rev 14243)
+++ trunk/reactos/subsys/csrss/win32csr/conio.c	2005-03-20 22:55:05 UTC (rev 14244)
@@ -1381,8 +1381,8 @@
     }
 }
 
-VOID
-Console_Api(DWORD RefreshEvent)
+DWORD STDCALL
+Console_Api (PVOID unused)
 {
   /* keep reading events from the keyboard and stuffing them into the current
      console's input queue */
@@ -1409,6 +1409,7 @@
     }
 
   PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
+  return 0;
 }
 
 CSR_API(CsrGetScreenBufferInfo)

Modified: trunk/reactos/subsys/smss/client.c
--- trunk/reactos/subsys/smss/client.c	2005-03-20 22:09:14 UTC (rev 14243)
+++ trunk/reactos/subsys/smss/client.c	2005-03-20 22:55:05 UTC (rev 14244)
@@ -99,14 +99,18 @@
  * SIDE EFFECTS
  * 	SmpClientDirectory.Lock is released only on success.
  */
-static PSM_CLIENT_DATA STDCALL
-SmpLookupClient (USHORT SubsystemId)
+static PSM_CLIENT_DATA FASTCALL
+SmpLookupClientUnsafe (USHORT           SubsystemId,
+		       PSM_CLIENT_DATA  * Parent)
 {
 	PSM_CLIENT_DATA Client = NULL;
 
-	DPRINT("SM: %s called\n", __FUNCTION__);
-
-	RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+	DPRINT("SM: %s(%d) called\n", __FUNCTION__, SubsystemId);
+	
+	if(NULL != Parent)
+	{
+		*Parent = NULL;
+	}
 	if (SmpClientDirectory.Count > 0)
 	{
 		Client = SmpClientDirectory.Client;
@@ -114,12 +118,31 @@
 		{
 			if (SubsystemId == Client->SubsystemId)
 			{
-				RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
-				return Client;
+				break;
 			}
+			if(NULL != Parent)
+			{
+				*Parent = Client;
+			}
 			Client = Client->Next;
 		}
 	}
+	return Client;
+}
+
+static PSM_CLIENT_DATA STDCALL
+SmpLookupClient (USHORT SubsystemId)
+{
+	PSM_CLIENT_DATA Client = NULL;
+
+	DPRINT("SM: %s called\n", __FUNCTION__);
[truncated at 1000 lines; 746 more skipped]