SM: init system reading the registry
authorEmanuele Aliberti <ea@iol.it>
Sun, 20 Mar 2005 22:55:05 +0000 (22:55 +0000)
committerEmanuele Aliberti <ea@iol.it>
Sun, 20 Mar 2005 22:55:05 +0000 (22:55 +0000)
CSR: register with SM for IMAGE_SUBSYSTEM_WINDOWS_CUI

svn path=/trunk/; revision=14244

14 files changed:
reactos/subsys/csrss/api/wapi.c
reactos/subsys/csrss/csrss.c
reactos/subsys/csrss/include/api.h
reactos/subsys/csrss/init.c
reactos/subsys/csrss/win32csr/conio.c
reactos/subsys/smss/client.c
reactos/subsys/smss/init.c
reactos/subsys/smss/initss.c
reactos/subsys/smss/makefile
reactos/subsys/smss/smapi.c
reactos/subsys/smss/smapiexec.c
reactos/subsys/smss/smapiquery.c [new file with mode: 0644]
reactos/subsys/smss/smss.c
reactos/subsys/smss/smss.h

index 0852c0a..406f5ea 100644 (file)
 
 /* 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 @@ CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
   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 @@ ClientConnectionThread(HANDLE ServerPort)
   PCSRSS_PROCESS_DATA ProcessData;
   PCSRSS_API_REPLY Reply;
    
+       DPRINT("CSR: %s called", __FUNCTION__);
+
   Reply = NULL;
    
   for (;;)
@@ -153,34 +162,37 @@ ClientConnectionThread(HANDLE ServerPort)
  *     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 @@ ServerApiPortThread (PVOID PortHandle)
                                     NULL,
                                     (PTHREAD_START_ROUTINE)ClientConnectionThread,
                                     ServerPort,
-                                    &ServerThread,
+                                    & ServerThread,
                                     NULL);
        if (!NT_SUCCESS(Status))
          {
@@ -230,6 +242,7 @@ ServerApiPortThread (PVOID PortHandle)
      }
    NtClose(PortHandle);
    NtTerminateThread(NtCurrentThread(), Status);
+   return 0;
 }
 
 /**********************************************************************
@@ -238,45 +251,88 @@ ServerApiPortThread (PVOID PortHandle)
  *
  * 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;
-               }
-               Status = NtCompleteConnectPort (hConnectedPort);
-               if(!NT_SUCCESS(Status))
-               {
-                       DPRINT1("CSR: %s: NtCompleteConnectPort() 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");
+                               }
+                       }
                }
-               /* 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 */
index b2b885e..9a2abea 100644 (file)
@@ -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 @@ CsrpFreeCommandLine (HANDLE                 ProcessHeap,
 }
 
 
-/**********************************************************************
- * 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.
index 0f8610e..eddf4d9 100644 (file)
@@ -82,6 +82,9 @@ PCSRSS_PROCESS_DATA ProcessData,\
 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 @@ NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions
 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;
 
index 106ad69..a694ab7 100644 (file)
 
 /* 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 @@ extern HANDLE CsrssApiHeap;
 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 @@ AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
   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 @@ CallInitComplete(void)
 ULONG
 InitializeVideoAddressSpace(VOID);
 
+/**********************************************************************
+ * CsrpParseCommandLine/2
+ */
 static NTSTATUS
-CsrParseCommandLine (
+CsrpParseCommandLine (
        ULONG ArgumentCount,
        PWSTR *ArgumentArray
        )
@@ -95,6 +115,8 @@ CsrParseCommandLine (
    NTSTATUS Status;
    OBJECT_ATTRIBUTES Attributes;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
 
    /*   DbgPrint ("Arguments: %ld\n", ArgumentCount);
    for (i = 0; i < ArgumentCount; i++)
@@ -114,21 +136,28 @@ CsrParseCommandLine (
                                    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();
 
@@ -148,10 +177,23 @@ CsrInitVideo(VOID)
     {
       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 @@ InitWin32Csr()
   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 @@ InitWin32Csr()
     }
   if (NULL != InitCompleteProc)
     {
-      Status = AddInitCompleteProc(InitCompleteProc);
+      Status = CsrpAddInitCompleteProc(InitCompleteProc);
     }
 
   return Status;
@@ -219,157 +263,292 @@ CSRSS_API_DEFINITION NativeDefinitions[] =
     { 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__);
+
+       CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
+                                      NULL,
+                                      65536,
+                                      65536,
+                                      NULL,
+                                      NULL);
+       if (CsrssApiHeap == NULL)
+       {
+               return STATUS_UNSUCCESSFUL;
+       }
+       return STATUS_SUCCESS;
+}
 
-       RtlInitUnicodeString (& SbApiPortName, L"\\Windows\\SbApiPort");
-       Status = SmConnectApiPort (& SbApiPortName,
-                                  (HANDLE)-1, //unused
+/**********************************************************************
+ * 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;
-
-DisplayString(L"CSR: CsrServerInitialization\n");
-
-  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;
-    }
+       INT       i = 0;
+       NTSTATUS  Status = STATUS_SUCCESS;
 
-  CsrInitVideo();
+       DPRINT("CSR: %s called\n", __FUNCTION__);
 
-  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 */
index 4c82d87..a9d5f6b 100644 (file)
@@ -1381,8 +1381,8 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     }
 }
 
-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 @@ Console_Api(DWORD RefreshEvent)
     }
 
   PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
+  return 0;
 }
 
 CSR_API(CsrGetScreenBufferInfo)
index 533ceea..33dc6bf 100644 (file)
@@ -99,14 +99,18 @@ SmCompleteClientInitialization (HANDLE hProcess)
  * SIDE EFFECTS\r
  *     SmpClientDirectory.Lock is released only on success.\r
  */\r
-static PSM_CLIENT_DATA STDCALL\r
-SmpLookupClient (USHORT SubsystemId)\r
+static PSM_CLIENT_DATA FASTCALL\r
+SmpLookupClientUnsafe (USHORT           SubsystemId,\r
+                      PSM_CLIENT_DATA  * Parent)\r
 {\r
        PSM_CLIENT_DATA Client = NULL;\r
 \r
-       DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
-       RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
+       DPRINT("SM: %s(%d) called\n", __FUNCTION__, SubsystemId);\r
+       \r
+       if(NULL != Parent)\r
+       {\r
+               *Parent = NULL;\r
+       }\r
        if (SmpClientDirectory.Count > 0)\r
        {\r
                Client = SmpClientDirectory.Client;\r
@@ -114,12 +118,31 @@ SmpLookupClient (USHORT SubsystemId)
                {\r
                        if (SubsystemId == Client->SubsystemId)\r
                        {\r
-                               RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
-                               return Client;\r
+                               break;\r
+                       }\r
+                       if(NULL != Parent)\r
+                       {\r
+                               *Parent = Client;\r
                        }\r
                        Client = Client->Next;\r
                }\r
        }\r
+       return Client;\r
+}\r
+\r
+static PSM_CLIENT_DATA STDCALL\r
+SmpLookupClient (USHORT SubsystemId)\r
+{\r
+       PSM_CLIENT_DATA Client = NULL;\r
+\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
+       RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
+       Client = SmpLookupClientUnsafe (SubsystemId, NULL);\r
+       if(NULL != Client)\r
+       {\r
+               RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
+       }\r
        /*\r
         * Note that we do *not* release SmpClientDirectory.Lock here\r
         * because SmpLookupClient is called to FAIL when SubsystemId\r
@@ -135,7 +158,7 @@ NTSTATUS STDCALL
 SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)\r
 {\r
        PSM_CLIENT_DATA pClient = NULL;\r
-       PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);\r
+       PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);\r
        ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);\r
 \r
        DPRINT("SM: %s called\n", __FUNCTION__);\r
@@ -206,16 +229,51 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
 \r
 /**********************************************************************\r
  *     SmpDestroyClient/1\r
+ *\r
+ *     1. close any handle\r
+ *     2. kill client process\r
+ *     3. release resources\r
  */\r
 NTSTATUS STDCALL\r
 SmDestroyClient (ULONG SubsystemId)\r
 {\r
+       NTSTATUS         Status = STATUS_SUCCESS;\r
+       PSM_CLIENT_DATA  Parent = NULL;\r
+       PSM_CLIENT_DATA  Client = NULL;\r
+\r
        DPRINT("SM: %s called\n", __FUNCTION__);\r
 \r
        RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
-       /* TODO */\r
+       Client = SmpLookupClientUnsafe (SubsystemId, & Parent);\r
+       if(NULL == Client)\r
+       {\r
+               DPRINT1("SM: %s: del req for non existent subsystem (id=%d)\n",\r
+                       __FUNCTION__, SubsystemId);\r
+               Status = STATUS_NOT_FOUND;\r
+       }\r
+       else\r
+       {\r
+               /* 1st in the list? */\r
+               if(NULL == Parent)\r
+               {\r
+                       SmpClientDirectory.Client = Client->Next;\r
+               }\r
+               else\r
+               {\r
+                       if(NULL != Parent)\r
+                       {\r
+                               Parent->Next = Client->Next;\r
+                       } else {\r
+                               DPRINT1("SM: %s: n-th has no parent!\n", __FUNCTION__);\r
+                               Status = STATUS_UNSUCCESSFUL; /* FIXME */\r
+                       }\r
+               }\r
+               /* TODO: send shutdown or kill */\r
+               RtlFreeHeap (SmpHeap, 0, Client);\r
+               -- SmpClientDirectory.Count;\r
+       }\r
        RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
-       return STATUS_SUCCESS;\r
+       return Status;\r
 }\r
 \r
 /* EOF */\r
index f3a1126..a8880e2 100644 (file)
@@ -39,7 +39,7 @@ SmpSignalInitEvent(VOID)
   NTSTATUS          Status = STATUS_SUCCESS;
   OBJECT_ATTRIBUTES ObjectAttributes = {0};
   UNICODE_STRING    EventName ={0};
-  HANDLE            ReactOSInitEvent = NULL;
+  HANDLE            ReactOSInitEvent = (HANDLE) 0;
 
   RtlInitUnicodeString (& EventName, L"\\ReactOSInitDone");
   InitializeObjectAttributes(&ObjectAttributes,
@@ -92,16 +92,13 @@ struct {
        {TRUE,  SmInitializeClientManagement, "initialize client management"},
        {TRUE,  SmLoadSubsystems,             "load subsystems"},
        {FALSE, SmpSignalInitEvent,           "open ReactOS init notification event"},
-       {TRUE,  SmRunCsrss,                   "run csrss"},
-       {TRUE,  SmRunWinlogon,                "run winlogon"},
-       {TRUE,  SmInitializeDbgSs,            "initialize DbgSs"}
 };
 
 NTSTATUS
 InitSessionManager(VOID)
 {
-  int i;
-  NTSTATUS Status;
+  INT i = 0;
+  NTSTATUS Status = STATUS_SUCCESS;
 
   for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
   {
@@ -118,8 +115,6 @@ InitSessionManager(VOID)
       }
     }
   }
-
-
   return(STATUS_SUCCESS);
 }
 
index 392595b..2c79c3a 100644 (file)
@@ -41,15 +41,9 @@ HANDLE hSmApiPort = (HANDLE) 0;
  * a) look if a special option is set for smss.exe in\r
  *    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\r
  *\r
- * b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE\r
- *    (programmatically)\r
- *\r
  * d) make smss initialize Debug (DBGSS) and Windows (CSRSS) as described\r
  *    in the registry key Required="Debug Windows"\r
  *    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\r
- *\r
- * e) make optional subsystems loadable (again: they must be described in the registry\r
- *    key Optional="Posix Os2" to be allowed to run)\r
  */\r
 \r
 /**********************************************************************\r
@@ -67,16 +61,17 @@ SmpRegisterSmss(VOID)
        NTSTATUS Status = STATUS_SUCCESS;\r
        UNICODE_STRING SbApiPortName = {0,0,NULL};\r
 \r
+       \r
        DPRINT("SM: %s called\n",__FUNCTION__);\r
 \r
        RtlInitUnicodeString (& SbApiPortName, L"");    \r
        Status = SmConnectApiPort(& SbApiPortName,\r
-                                 (HANDLE) 0,\r
+                                 (HANDLE) -1, /* SM has no SB port */\r
                                  IMAGE_SUBSYSTEM_NATIVE,\r
                                  & hSmApiPort);\r
        if(!NT_SUCCESS(Status))\r
        {\r
-               DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",\r
+               DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",\r
                        __FUNCTION__,Status);\r
                return Status;\r
        }\r
@@ -91,27 +86,19 @@ SmpRegisterSmss(VOID)
 \r
 \r
 /**********************************************************************\r
+ *     SmpLoadKernelModeSubsystem/0\r
  */\r
-NTSTATUS\r
-SmLoadSubsystems(VOID)\r
+static NTSTATUS\r
+SmpLoadKernelModeSubsystem (VOID)\r
 {\r
-       SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
-       NTSTATUS                   Status = STATUS_SUCCESS;\r
-       WCHAR                      Data [MAX_PATH + 1];\r
-       ULONG                      DataLength = sizeof Data;\r
-       ULONG                      DataType = 0;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+       WCHAR     Data [MAX_PATH + 1];\r
+       ULONG     DataLength = sizeof Data;\r
+       ULONG     DataType = 0;\r
 \r
 \r
-       DPRINT("SM: loading subsystems\n");\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
 \r
-       /* SM self registers */\r
-       Status = SmpRegisterSmss();\r
-       if(!NT_SUCCESS(Status))\r
-       {\r
-               DPRINT1("SM: SM failed to self register: system is not secure!\n");\r
-       }\r
-\r
-       /* Load Kmode subsystem (aka win32k.sys) */\r
        Status = SmLookupSubsystem (L"Kmode",\r
                                    Data,\r
                                    & DataLength,\r
@@ -119,128 +106,101 @@ SmLoadSubsystems(VOID)
                                    TRUE);\r
        if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
        {\r
-               WCHAR ImagePath [MAX_PATH + 1] = {0};\r
+               WCHAR                      ImagePath [MAX_PATH + 1] = {0};\r
+               SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
 \r
                wcscpy (ImagePath, L"\\??\\");\r
                wcscat (ImagePath, Data);\r
                RtlZeroMemory (& ImageInfo, sizeof ImageInfo);\r
                RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);\r
                Status = NtSetSystemInformation(SystemLoadAndCallImage,\r
-                                         & ImageInfo,\r
-                                         sizeof ImageInfo);\r
+                                               & ImageInfo,\r
+                                               sizeof ImageInfo);\r
                if(!NT_SUCCESS(Status))\r
                {\r
-                       DPRINT("SM: loading Kmode failed (Status=0x%08lx)\n",\r
-                               Status);\r
-                       return Status;\r
+                       DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",\r
+                               __FUNCTION__, Status);\r
                }\r
        }\r
-       /* TODO: load Required subsystems (Debug Windows) */\r
-#if 0\r
-       Status = SmExecuteProgram (hSmApiPort, L"DEBUG");\r
-       if(!NT_SUCCESS(Status))\r
-       {\r
-               DPRINT1("SM: DBSS failed to initialize!\n");\r
-       }\r
-#endif\r
        return Status;\r
 }\r
 \r
-NTSTATUS\r
-SmRunCsrss(VOID)\r
+/**********************************************************************\r
+ *     SmpLoadRequiredSubsystems/0\r
+ */\r
+static NTSTATUS\r
+SmpLoadRequiredSubsystems (VOID)\r
 {\r
-  NTSTATUS Status;\r
-  UNICODE_STRING UnicodeString;\r
-  OBJECT_ATTRIBUTES ObjectAttributes;\r
-  RTL_PROCESS_INFO ProcessInfo;\r
-  HANDLE CsrssInitEvent;\r
-  WCHAR ImagePath [MAX_PATH];\r
-\r
-  DPRINT("SM: initializing csrss\n");\r
-\r
-  /* Run csrss.exe */\r
-  RtlRosInitUnicodeStringFromLiteral(&UnicodeString,\r
-                                 L"\\CsrssInitDone");\r
-  InitializeObjectAttributes(&ObjectAttributes,\r
-                            &UnicodeString,\r
-                            EVENT_ALL_ACCESS,\r
-                            0,\r
-                            NULL);\r
-  Status = NtCreateEvent(&CsrssInitEvent,\r
-                        EVENT_ALL_ACCESS,\r
-                        &ObjectAttributes,\r
-                        NotificationEvent,\r
-                        FALSE);\r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DbgPrint("Failed to create csrss notification event\n");\r
-    }\r
-\r
-  /*\r
-   * Start the Win32 subsystem (csrss.exe)\r
-   */\r
-\r
-  /* initialize executable path */\r
-  wcscpy(ImagePath, L"\\??\\");\r
-  wcscat(ImagePath, SharedUserData->NtSystemRoot);\r
-  wcscat(ImagePath, L"\\system32\\csrss.exe");\r
-\r
-  Status = SmCreateUserProcess(ImagePath,\r
-                               L"",\r
-                               FALSE, /* wait */\r
-                               NULL,\r
-                               FALSE, /* terminate */\r
-                               & ProcessInfo);\r
-  \r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__);\r
-      return(Status);\r
-    }\r
-\r
-  Status = NtWaitForSingleObject(CsrssInitEvent,\r
-                       FALSE,\r
-                       NULL);\r
-\r
-  Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;\r
-\r
-  return Status;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+       WCHAR     Data [MAX_PATH + 1];\r
+       ULONG     DataLength = sizeof Data;\r
+       ULONG     DataType = 0;\r
+\r
+       \r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
+       RtlZeroMemory (Data, DataLength);\r
+       Status = SmLookupSubsystem (L"Required",\r
+                                   Data,\r
+                                   & DataLength,\r
+                                   & DataType,\r
+                                   FALSE);\r
+       if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
+       {\r
+               PWCHAR Name = NULL;\r
+               ULONG Offset = 0;\r
+               \r
+               for (Name = Data; (Offset < DataLength); )\r
+               {\r
+                       if(L'\0' != *Name)\r
+                       {\r
+                               UNICODE_STRING Program;\r
+\r
+                               /* Run the current program */\r
+                               RtlInitUnicodeString (& Program, Name);\r
+                               Status = SmExecuteProgram (hSmApiPort, & Program);\r
+                               if(!NT_SUCCESS(Status))\r
+                               {\r
+                                       DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",\r
+                                               __FUNCTION__, Name, Status);\r
+                               }\r
+                               /* Look for the next program */\r
+                               while ((L'\0' != *Name) && (Offset < DataLength))\r
+                               {\r
+                                       ++ Name;\r
+                                       ++ Offset;\r
+                               }\r
+                       }\r
+                       ++ Name;\r
+                       ++ Offset;\r
+               }\r
+       }\r
+\r
+       return Status;\r
 }\r
 \r
+/**********************************************************************\r
+ *     SmLoadSubsystems/0\r
+ */\r
 NTSTATUS\r
-SmRunWinlogon(VOID)\r
+SmLoadSubsystems(VOID)\r
 {\r
-  NTSTATUS         Status = STATUS_SUCCESS;\r
-  RTL_PROCESS_INFO ProcessInfo;\r
-  WCHAR            ImagePath [MAX_PATH];\r
-\r
-  /*\r
-   * Start the logon process (winlogon.exe)\r
-   */\r
-\r
-  DPRINT("SM: starting winlogon\n");\r
-\r
-  /* initialize executable path */\r
-  wcscpy(ImagePath, L"\\??\\");\r
-  wcscat(ImagePath, SharedUserData->NtSystemRoot);\r
-  wcscat(ImagePath, L"\\system32\\winlogon.exe");\r
-\r
-  Status = SmCreateUserProcess(ImagePath,\r
-                               L"",\r
-                               FALSE, /* wait */\r
-                               NULL,\r
-                               FALSE, /* terminate */\r
-                               & ProcessInfo);\r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);\r
-      NtTerminateProcess(Children[CHILD_CSRSS], 0);\r
-      return(Status);\r
-    }\r
-\r
-  Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;\r
-\r
-  return Status;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+\r
+       \r
+       DPRINT("SM: loading subsystems\n");\r
+\r
+       /* SM self registers */\r
+       Status = SmpRegisterSmss();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* Load Kmode subsystem (aka win32k.sys) */\r
+       Status = SmpLoadKernelModeSubsystem();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* Load Required subsystems (Debug Windows) */\r
+       Status = SmpLoadRequiredSubsystems();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* done */\r
+       return Status;\r
 }\r
 \r
 /* EOF */\r
index ebfc47e..3845a34 100644 (file)
@@ -21,7 +21,7 @@ TARGET_OBJECTS = $(TARGET_NAME).o \
                 init.o initheap.o initenv.o initobdir.o initdosdev.o \
                 initrun.o initmv.o initwkdll.o initpage.o initss.o \
                 initreg.o \
-                smapi.o smapicomp.o smapiexec.o \
+                smapi.o smapicomp.o smapiexec.o smapiquery.o \
                 client.o debug.o print.o
 
 include $(PATH_TO_TOP)/rules.mak
index 62a72f2..a157850 100644 (file)
@@ -34,14 +34,63 @@ SM_PORT_API SmApi [] =
        SmCompSes,      /* smapicomp.c */
        SmInvalid,      /* obsolete */
        SmInvalid,      /* unknown */
-       SmExecPgm       /* smapiexec.c */
+       SmExecPgm,      /* smapiexec.c */
+       SmQryInfo       /* smapyqry.c */
 };
 
+/* TODO: optimize this address computation (it should be done 
+ * with a macro) */
+PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE Request)
+{
+       PLPC_MAX_MESSAGE LpcMaxMessage = (PLPC_MAX_MESSAGE) Request;
+       return (PSM_CONNECT_DATA) & LpcMaxMessage->Data[0];
+}
+
 #if !defined(__USE_NT_LPC__)
 NTSTATUS STDCALL
 SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request);
 #endif
 
+/**********************************************************************
+ * SmpCallback/2
+ *
+ * The SM calls back a previously connected subsystem process to
+ * authorizes it to bootstrap (initialize). The SM connects to a
+ * named LPC port which name was sent in the connection data by the
+ * candidate subsystem server process.
+ */
+static NTSTATUS
+SmpCallbackServer (PSM_PORT_MESSAGE Request,
+                  PSM_CLIENT_DATA ClientData)
+{
+       NTSTATUS          Status = STATUS_SUCCESS;
+       PSM_CONNECT_DATA  ConnectData = SmpGetConnectData (Request);
+       UNICODE_STRING    CallbackPortName;
+       ULONG             CallbackPortNameLength = SM_SB_NAME_MAX_LENGTH; /* TODO: compute length */
+       
+       DPRINT("SM: %s called\n", __FUNCTION__);
+
+       if(IMAGE_SUBSYSTEM_NATIVE == ConnectData->Subsystem)
+       {
+               DPRINT("SM: %s: we do not need calling back SM!\n",
+                               __FUNCTION__);
+               return STATUS_SUCCESS;
+       }
+       RtlCopyMemory (ClientData->SbApiPortName,
+                      ConnectData->SbName,
+                      CallbackPortNameLength);
+       RtlInitUnicodeString (& CallbackPortName,
+                             ClientData->SbApiPortName);
+       Status = NtConnectPort (& ClientData->SbApiPort,
+                               & CallbackPortName,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL);
+       return Status;
+}
 
 /**********************************************************************
  * NAME
@@ -59,8 +108,7 @@ SmpApiConnectedThread(PVOID pConnectedPort)
        SM_PORT_MESSAGE Request = {{0}};
        HANDLE          ConnectedPort = * (PHANDLE) pConnectedPort;
 
-       DPRINT("SM: %s(%08lx) running\n", __FUNCTION__, pConnectedPort);
-       DPRINT("SM: %s(%08lx): ConnectedPort = %08lx\n",  __FUNCTION__, pConnectedPort, ConnectedPort);
+       DPRINT("SM: %s called\n", __FUNCTION__);
 
        while (TRUE)
        {
@@ -122,7 +170,7 @@ SmpApiConnectedThread(PVOID pConnectedPort)
 NTSTATUS STDCALL
 SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
 {
-       PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);
+       PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);
        NTSTATUS         Status = STATUS_SUCCESS;
        BOOL             Accept = FALSE;
        PSM_CLIENT_DATA  ClientData = NULL;
@@ -132,46 +180,69 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
        PHANDLE          ClientDataApiPortThread = & hClientDataApiPortThread;
        PVOID            Context = NULL;
        
-       DPRINT("SM: %s called\n", __FUNCTION__);
+       DPRINT("SM: %s called:\n  SubSystemID=%d\n  SbName=\"%S\"\n",
+                       __FUNCTION__, ConnectData->Subsystem, ConnectData->SbName);
 
        if(sizeof (SM_CONNECT_DATA) == Request->Header.DataSize)
        {
                if(IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->Subsystem)
                {
                        /*
-                        * This is not a call from an environment server
-                        * willing to register, but from any other process
+                        * This is not a call to register an image set,
+                        * but a simple connection request from a process
                         * that will use the SM API.
                         */
-                       DPRINT("SM: %s: req from NON subsys server process\n", __FUNCTION__);
+                       DPRINT("SM: %s: simple request\n", __FUNCTION__);
                        ClientDataApiPort = & hClientDataApiPort;
                        ClientDataApiPortThread = & hClientDataApiPortThread;
                        Accept = TRUE;
                } else {
-                       DPRINT("SM: %s: req from subsys server process\n", __FUNCTION__);
+                       DPRINT("SM: %s: request to register an image set\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).
+                        *  Reject GUIs classes: only odd subsystem IDs are
+                        *  allowed to register here (tty mode images).
                         */
-                       Status = SmCreateClient (Request, & ClientData);
-                       if(STATUS_SUCCESS == Status)
+                       if(1 == (ConnectData->Subsystem % 2))
                        {
-                               /* OK: the client is an environment subsystem
-                                * willing to manage a free image type.
-                                */
-                               ClientDataApiPort = & ClientData->ApiPort;
-                               ClientDataApiPortThread = & ClientData->ApiPortThread;
+                               DPRINT("SM: %s: id = %d\n", __FUNCTION__, ConnectData->Subsystem);
                                /*
-                                *  Reject GUIs: only odd subsystem IDs are
-                                *  allowed to register here.
+                                * 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)
                                 */
-                               Accept = (1 == (ConnectData->Subsystem % 2));
+                               Status = SmCreateClient (Request, & ClientData);
+                               if(STATUS_SUCCESS == Status)
+                               {
+                                       DPRINT("SM: %s: ClientData = 0x%08lx\n",
+                                               __FUNCTION__, ClientData);
+                                       /*
+                                        * OK: the client is an environment subsystem
+                                        * willing to manage a free image type.
+                                        */
+                                       ClientDataApiPort = & ClientData->ApiPort;
+                                       ClientDataApiPortThread = & ClientData->ApiPortThread;
+                                       /*
+                                        * Call back the candidate environment subsystem
+                                        * server (use the port name sent in in the 
+                                        * connection request message).
+                                        */
+                                       Status = SmpCallbackServer (Request, ClientData);
+                                       if(NT_SUCCESS(Status))
+                                       {
+                                               DPRINT("SM: %s: SmpCallbackServer OK\n",
+                                                       __FUNCTION__);
+                                               Accept = TRUE;
+                                       } else {
+                                               DPRINT("SM: %s: SmpCallbackServer failed (Status=%08lx)\n",
+                                                       __FUNCTION__, Status);
+                                               Status = SmDestroyClient (ConnectData->Subsystem);
+                                       }
+                               }
                        }
                }
        }
+       DPRINT("SM: %s: before NtAcceptConnectPort\n", __FUNCTION__);
 #if defined(__USE_NT_LPC__)
        Status = NtAcceptConnectPort (ClientDataApiPort,
                                      Context,
@@ -187,8 +258,6 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
                                      NULL,
                                      NULL);
 #endif
-       DPRINT("SM: %s: ClientDataPort=0x%08lx\n", __FUNCTION__, ClientDataApiPort);
-       DPRINT("SM: %s: *ClientDataPort=0x%08lx\n", __FUNCTION__, *ClientDataApiPort);
        if(Accept)
        {
                if(!NT_SUCCESS(Status))
@@ -247,6 +316,8 @@ SmpApiThread (HANDLE ListeningPort)
 {
        NTSTATUS        Status = STATUS_SUCCESS;
        LPC_MAX_MESSAGE Request = {{0}};
+
+       DPRINT("SM: %s called\n", __FUNCTION__);
     
        while (TRUE)
        {
index 744a094..ad83e51 100644 (file)
@@ -83,16 +83,8 @@ SmCreateUserProcess (LPWSTR ImagePath,
                                       pProcessInfo);\r
        if (!NT_SUCCESS(Status))\r
        {\r
-               CHAR AnsiBuffer [MAX_PATH];\r
-               INT i = 0;\r
-               for(i=0;ImagePathString.Buffer[i];i++)\r
-               {\r
-                       /* raw U -> A */\r
-                       AnsiBuffer [i] = (CHAR) (ImagePathString.Buffer[i] & 0xff);\r
-               }\r
-\r
-               DPRINT1("SM: %s: Running \"%s\" failed (Status=0x%08lx)\n",\r
-                       AnsiBuffer, __FUNCTION__, Status);\r
+               DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n",\r
+                       __FUNCTION__, ImagePathString.Buffer, Status);\r
                return Status;\r
        }\r
 \r
@@ -145,7 +137,7 @@ SmLookupSubsystem (IN     PWSTR   Name,
        OBJECT_ATTRIBUTES  Oa = {0};\r
        HANDLE             hKey = (HANDLE) 0;\r
 \r
-       DPRINT("SM: %s called\n", __FUNCTION__);\r
+       DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);\r
        /*\r
         * Prepare the key name to scan and\r
         * related object attributes.\r
@@ -268,7 +260,7 @@ SMAPI(SmExecPgm)
                RtlCopyMemory (Name,\r
                               ExecPgm->Name,\r
                               (sizeof ExecPgm->Name[0] * ExecPgm->NameLength));\r
-               DPRINT("SM: %s: Name=[%wZ]\n", __FUNCTION__, Name);\r
+               DPRINT("SM: %s: Name='%S'\n", __FUNCTION__, Name);\r
                /*\r
                 * Check if program name is internal\r
                 * (Is this correct? Debug is in the registry too)\r
diff --git a/reactos/subsys/smss/smapiquery.c b/reactos/subsys/smss/smapiquery.c
new file mode 100644 (file)
index 0000000..e93e593
--- /dev/null
@@ -0,0 +1,46 @@
+/* $Id: $\r
+ *\r
+ * smapiquery.c - SM_API_QUERY_INFORMATION\r
+ *\r
+ * Reactos Session Manager\r
+ *\r
+ * --------------------------------------------------------------------\r
+ *\r
+ * This software is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 2 of the\r
+ * License, or (at your option) any later version.\r
+ *\r
+ * This software is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this software; see the file COPYING.LIB. If not, write\r
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
+ * MA 02139, USA.  \r
+ *\r
+ * --------------------------------------------------------------------\r
+ */\r
+#include "smss.h"\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+\r
+/**********************************************************************\r
+ * SmQryInfo/1                                                 API\r
+ */\r
+SMAPI(SmQryInfo)\r
+{\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+       \r
+       Request->Status = STATUS_NOT_IMPLEMENTED;\r
+       return Status;\r
+}\r
+\r
+\r
+/* EOF */\r
index a6a983f..b03197c 100644 (file)
@@ -56,6 +56,7 @@ NtProcessStartup(PPEB Peb)
   }
   /* Initialize the system */
   Status = InitSessionManager();
+#if 0
   if (!NT_SUCCESS(Status))
     {
       int i;
@@ -90,6 +91,8 @@ ByeBye:
                   0,0,0,0,0);
 
 //   NtTerminateProcess(NtCurrentProcess(), 0);
+#endif
+       NtTerminateThread(NtCurrentThread(), Status);
 }
 
 /* EOF */
index 03ad2e3..eae6143 100644 (file)
@@ -49,12 +49,14 @@ NTSTATUS SmInitializeRegistry(VOID);
 
 /* initss.c */
 NTSTATUS SmLoadSubsystems(VOID);
-NTSTATUS SmRunCsrss(VOID);
-NTSTATUS SmRunWinlogon(VOID);
 
 /* smapi.c */
 #define SMAPI(n) \
 NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request)
+PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE);
+NTSTATUS SmCreateApiPort(VOID);
+VOID STDCALL SmpApiThread(PVOID);
+
 
 /* smapiexec.c */
 NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath,
@@ -74,8 +76,8 @@ NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE);
 /* smapicomp.c */
 NTSTATUS FASTCALL SmCompSes(PSM_PORT_MESSAGE);
 
-NTSTATUS SmCreateApiPort(VOID);
-VOID STDCALL SmpApiThread(PVOID);
+/* smapiquery.c */
+NTSTATUS FASTCALL SmQryInfo(PSM_PORT_MESSAGE);
 
 /* client.c */
 typedef struct _SM_CLIENT_DATA