Author: ion
Date: Tue Feb  7 07:13:42 2012
New Revision: 55478

URL: http://svn.reactos.org/svn/reactos?rev=55478&view=rev
Log:
[SMSS2]: Implement executing the initial command as well as doing the SM-to-SM 
initial connection.
[SMSS2]: Implement the main LPC loop and handle all the supported APIs (all 
stubs for now). Also handle new connection requests and implement 
SmpHandleConnectionRequest.
[SMSS2]: Implement subsystem helper functions.
[SMSS2]: Use SmApiPort2 instead of Sm2ApiPort.
[SMSS2]: Rename the SMSRV_APIs not to conflict with the function names, nor 
with the client functions in smlib.

Modified:
    trunk/reactos/base/system/smss2/CMakeLists.txt
    trunk/reactos/base/system/smss2/sminit.c
    trunk/reactos/base/system/smss2/smloop.c
    trunk/reactos/base/system/smss2/smsessn.c
    trunk/reactos/base/system/smss2/smss.c
    trunk/reactos/base/system/smss2/smss.h
    trunk/reactos/base/system/smss2/smss2.rbuild
    trunk/reactos/base/system/smss2/smsubsys.c
    trunk/reactos/include/reactos/subsys/sm/smmsg.h

Modified: trunk/reactos/base/system/smss2/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/CMakeLists.txt?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/CMakeLists.txt [iso-8859-1] Tue Feb  7 
07:13:42 2012
@@ -15,7 +15,7 @@
 
 add_executable(smss2 WIN32 ${SOURCE})
 
-target_link_libraries(smss2 nt pseh)
+target_link_libraries(smss2 nt pseh smlib)
 
 add_pch(smss2 smss.h)
 

Modified: trunk/reactos/base/system/smss2/sminit.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/sminit.c?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/sminit.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/sminit.c [iso-8859-1] Tue Feb  7 07:13:42 
2012
@@ -2439,7 +2439,7 @@
     RtlInitUnicodeString(&Os2Name, L"OS2");
 
     /* Create the SM API Port */
-    RtlInitUnicodeString(&PortName, L"\\Sm2ApiPort");
+    RtlInitUnicodeString(&PortName, L"\\SmApiPort2");
     InitializeObjectAttributes(&ObjectAttributes, &PortName, 0, NULL, NULL);
     Status = NtCreatePort(&PortHandle,
                           &ObjectAttributes,

Modified: trunk/reactos/base/system/smss2/smloop.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smloop.c?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smloop.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smloop.c [iso-8859-1] Tue Feb  7 07:13:42 
2012
@@ -14,7 +14,263 @@
 
 /* GLOBALS 
********************************************************************/
 
+typedef struct _SMP_CLIENT_CONTEXT
+{
+    PVOID Subsystem;
+    HANDLE ProcessHandle;
+    HANDLE PortHandle;
+    ULONG dword10;
+} SMP_CLIENT_CONTEXT, *PSMP_CLIENT_CONTEXT;
+
+typedef
+NTSTATUS
+(NTAPI *PSM_API_HANDLER)(
+     IN PSM_API_MSG SmApiMsg,
+     IN PSMP_CLIENT_CONTEXT ClientContext,
+     IN HANDLE SmApiPort
+);
+
+volatile LONG SmTotalApiThreads;
+HANDLE SmUniqueProcessId;
+
+/* API HANDLERS 
***************************************************************/
+
+NTSTATUS
+NTAPI
+SmpCreateForeignSession(IN PSM_API_MSG SmApiMsg,
+                        IN PSMP_CLIENT_CONTEXT ClientContext,
+                        IN HANDLE SmApiPort)
+{
+    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+SmpSessionComplete(IN PSM_API_MSG SmApiMsg,
+                   IN PSMP_CLIENT_CONTEXT ClientContext,
+                   IN HANDLE SmApiPort)
+{
+    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+SmpTerminateForeignSession(IN PSM_API_MSG SmApiMsg,
+                           IN PSMP_CLIENT_CONTEXT ClientContext,
+                           IN HANDLE SmApiPort)
+{
+    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+SmpExecPgm(IN PSM_API_MSG SmApiMsg,
+           IN PSMP_CLIENT_CONTEXT ClientContext,
+           IN HANDLE SmApiPort)
+{
+    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+SmpLoadDeferedSubsystem(IN PSM_API_MSG SmApiMsg,
+                        IN PSMP_CLIENT_CONTEXT ClientContext,
+                        IN HANDLE SmApiPort)
+{
+    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+SmpStartCsr(IN PSM_API_MSG SmApiMsg,
+            IN PSMP_CLIENT_CONTEXT ClientContext,
+            IN HANDLE SmApiPort)
+{
+    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+SmpStopCsr(IN PSM_API_MSG SmApiMsg,
+           IN PSMP_CLIENT_CONTEXT ClientContext,
+           IN HANDLE SmApiPort)
+{
+    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
+    return STATUS_SUCCESS;
+}
+
+PSM_API_HANDLER SmpApiDispatch[SmMaxApiNumber] =
+{
+    SmpCreateForeignSession,
+    SmpSessionComplete,
+    SmpTerminateForeignSession,
+    SmpExecPgm,
+    SmpLoadDeferedSubsystem,
+    SmpStartCsr,
+    SmpStopCsr
+};
+
 /* FUNCTIONS 
******************************************************************/
+
+NTSTATUS
+NTAPI
+SmpHandleConnectionRequest(IN HANDLE SmApiPort,
+                           IN PSB_API_MSG SbApiMsg)
+{
+    BOOLEAN Accept = TRUE;
+    HANDLE PortHandle, ProcessHandle;
+    ULONG SessionId;
+    UNICODE_STRING SubsystemPort;
+    SMP_CLIENT_CONTEXT *ClientContext;
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    REMOTE_PORT_VIEW PortView;
+    SECURITY_QUALITY_OF_SERVICE SecurityQos;
+    PSMP_SUBSYSTEM CidSubsystem, TypeSubsystem;
+
+    /* Initialize QoS data */
+    SecurityQos.ImpersonationLevel = SecurityIdentification;
+    SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
+    SecurityQos.EffectiveOnly = TRUE;
+
+    /* Check if this is SM connecting to itself */
+    if (SbApiMsg->h.ClientId.UniqueProcess == SmUniqueProcessId)
+    {
+        /* No need to get any handle -- assume session 0 */
+        DPRINT1("SM connecting to SM\n");
+        ProcessHandle = NULL;
+        SessionId = 0;
+    }
+    else
+    {
+        /* Reference the foreign process */
+        DPRINT1("Incoming request from %lx\n", 
SbApiMsg->h.ClientId.UniqueProcess);
+        InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+        Status = NtOpenProcess(&ProcessHandle,
+                               PROCESS_QUERY_INFORMATION,
+                               &ObjectAttributes,
+                               &SbApiMsg->h.ClientId);
+        if (!NT_SUCCESS(Status)) Accept = FALSE;
+
+        /* Get its session ID */
+        SmpGetProcessMuSessionId(ProcessHandle, &SessionId);
+    }
+
+    /* See if we already know about the caller's subystem */
+    CidSubsystem = SmpLocateKnownSubSysByCid(&SbApiMsg->h.ClientId);
+    if ((CidSubsystem) && (Accept))
+    {
+        /* Check if we already have a subsystem for this kind of image */
+        TypeSubsystem = SmpLocateKnownSubSysByType(SessionId,
+                                                   
SbApiMsg->ConnectionInfo.SubsystemType);
+        if (TypeSubsystem == CidSubsystem)
+        {
+            /* Someone is trying to take control of an existing subsystem, 
fail */
+            Accept = FALSE;
+            DPRINT1("SMSS: Connection from SubSystem rejected\n");
+            DPRINT1("SMSS: Image type already being served\n");
+        }
+        else
+        {
+            /* Set this image type as the type for this subsystem */
+            CidSubsystem->ImageType = SbApiMsg->ConnectionInfo.SubsystemType;
+        }
+
+        /* Drop the reference we had acquired */
+        if (TypeSubsystem) SmpDereferenceSubsystem(TypeSubsystem);
+    }
+
+    /* Check if we'll be accepting the connection */
+    if (Accept)
+    {
+        /* We will, so create a client context for it */
+        ClientContext = RtlAllocateHeap(SmpHeap, 0, 
sizeof(SMP_CLIENT_CONTEXT));
+        if (ClientContext)
+        {
+            ClientContext->ProcessHandle = ProcessHandle;
+            ClientContext->Subsystem = CidSubsystem;
+            ClientContext->dword10 = 0;
+            ClientContext->PortHandle = NULL;
+        }
+        else
+        {
+            /* Failed to allocate a client context, so reject the connection */
+            DPRINT1("Rejecting connectiond due to lack of memory\n");
+            Accept = FALSE;
+        }
+    }
+    else
+    {
+        /* Use a bogus context since we're going to reject the message */
+        ClientContext = (PSMP_CLIENT_CONTEXT)SbApiMsg;
+    }
+
+    /* Now send the actual accept reply (which could be a rejection) */
+    PortView.Length = sizeof(PortView);
+    DPRINT1("Accepting: %d connection with context: %p\n", Accept, 
ClientContext);
+    Status = NtAcceptConnectPort(&PortHandle,
+                                 ClientContext,
+                                 &SbApiMsg->h,
+                                 Accept,
+                                 NULL,
+                                 &PortView);
+    if (!(Accept) || !(NT_SUCCESS(Status)))
+    {
+        /* Close the process handle, reference the subsystem, and exit */
+        DPRINT1("Accept failed or rejected: %lx\n", Status);
+        if (ClientContext != (PVOID)SbApiMsg) RtlFreeHeap(SmpHeap, 0, 
ClientContext);
+        if (ProcessHandle) NtClose(ProcessHandle);
+        if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
+        return Status;
+    }
+
+    /* Save the port handle now that we've accepted it */
+    if (ClientContext) ClientContext->PortHandle = PortHandle;
+    if (CidSubsystem) CidSubsystem->PortHandle = PortHandle;
+
+    /* Complete the port connection */
+    Status = NtCompleteConnectPort(PortHandle);
+    if ((NT_SUCCESS(Status)) && (CidSubsystem))
+    {
+        /* This was an actual subsystem, so connect back to it */
+        DPRINT1("Connecting back to %wZ\n", &SubsystemPort);
+        SbApiMsg->ConnectionInfo.SbApiPortName[119] = UNICODE_NULL;
+        RtlCreateUnicodeString(&SubsystemPort,
+                               SbApiMsg->ConnectionInfo.SbApiPortName);
+        Status = NtConnectPort(&CidSubsystem->SbApiPort,
+                               &SubsystemPort,
+                               &SecurityQos,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("SMSS: Connect back to Sb %wZ failed %lx\n", 
&SubsystemPort, Status);
+        }
+        RtlFreeUnicodeString(&SubsystemPort);
+
+        /* Now that we're connected, signal the event handle */
+        NtSetEvent(CidSubsystem->Event, NULL);
+    }
+    else if (CidSubsystem)
+    {
+        /* We failed to complete the connection, so clear the port handle */
+        DPRINT1("Completing the connection failed: %lx\n", Status);
+        CidSubsystem->PortHandle = NULL;
+    }
+
+    /* Dereference the subsystem and return the result */
+    if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem);
+    return Status;
+}
 
 ULONG
 NTAPI
@@ -22,18 +278,101 @@
 {
     HANDLE SmApiPort = (HANDLE)Parameter;
     NTSTATUS Status;
-    PVOID ClientContext;
-    PSM_API_MSG RequestMsg = NULL;
-    SM_API_MSG ReplyMsg;
-
-    DPRINT1("API Loop: %p\n", SmApiPort);
+    PSMP_CLIENT_CONTEXT ClientContext;
+    PSM_API_MSG ReplyMsg = NULL;
+    SM_API_MSG RequestMsg;
+    PROCESS_BASIC_INFORMATION ProcessInformation;
+    LARGE_INTEGER Timeout;
+
+    /* Increase the number of API threads for throttling code for later */
+    _InterlockedExchangeAdd(&SmTotalApiThreads, 1);
+
+    /* Mark us critical */
+    RtlSetThreadIsCritical(TRUE, NULL, TRUE);
+
+    /* Set the PID of the SM process itself for later checking */
+    NtQueryInformationProcess(NtCurrentProcess(),
+                              ProcessBasicInformation,
+                              &ProcessInformation,
+                              sizeof(ProcessInformation),
+                              NULL);
+    SmUniqueProcessId = (HANDLE)ProcessInformation.UniqueProcessId;
+
+    /* Now process incoming messages */
     while (TRUE)
     {
+        /* Begin waiting on a request */
+        DPRINT1("API Loop: %p\n", SmApiPort);
         Status = NtReplyWaitReceivePort(SmApiPort,
-                                        &ClientContext,
-                                        &RequestMsg->h,
-                                        &ReplyMsg.h);
-        DPRINT1("API loop returned: %lx\n", Status);
-    }
-    return STATUS_SUCCESS;
-}
+                                        (PVOID*)&ClientContext,
+                                        &ReplyMsg->h,
+                                        &RequestMsg.h);
+        if (Status == STATUS_NO_MEMORY)
+        {
+            /* Ran out of memory, so do a little timeout and try again */
+            if (ReplyMsg) DPRINT1("SMSS: Failed to reply to calling thread, 
retrying.\n");
+            Timeout.QuadPart = -50000000;
+            NtDelayExecution(FALSE, &Timeout);
+            continue;
+        }
+
+        /* Check what kind of request we received */
+        switch (RequestMsg.h.u2.s2.Type)
+        {
+            /* A new connection */
+            case LPC_CONNECTION_REQUEST:
+                /* Create the right structures for it */
+                DPRINT1("New connection request\n");
+                SmpHandleConnectionRequest(SmApiPort, 
(PSB_API_MSG)&RequestMsg);
+                ReplyMsg =  NULL;
+                break;
+
+            /* A closed connection */
+            case LPC_PORT_CLOSED:
+                /* Destroy any state we had for this client */
+                DPRINT1("Port closed\n");
+                //if (ClientContext) 
SmpPushDeferredClientContext(ClientContext);
+                ReplyMsg = NULL;
+                break;
+
+            /* An actual API message */
+            default:
+                if (!ClientContext)
+                {
+                    ReplyMsg = NULL;
+                    break;
+                }
+
+                RequestMsg.ReturnValue = STATUS_PENDING;
+
+                /* Check if the API is valid */
+                if (RequestMsg.ApiNumber >= SmMaxApiNumber)
+                {
+                    /* It isn't, fail */
+                    DPRINT1("Invalid API: %lx\n", RequestMsg.ApiNumber);
+                    Status = STATUS_NOT_IMPLEMENTED;
+                }
+                else if ((RequestMsg.ApiNumber <= 
SmTerminateForeignSessionApi) &&
+                         !(ClientContext->Subsystem))
+                {
+                    /* It's valid, but doesn't have a subsystem with it */
+                    DPRINT1("Invalid session API\n");
+                    Status = STATUS_INVALID_PARAMETER;
+                }
+                else
+                {
+                    /* It's totally okay, so call the dispatcher for it */
+                    DPRINT1("Calling dispatcher for ID: %lx\n", 
RequestMsg.ApiNumber);
+                    Status = SmpApiDispatch[RequestMsg.ApiNumber](&RequestMsg,
+                                                                  
ClientContext,
+                                                                  SmApiPort);
+                }
+
+                /* Write the result valud and return the message back */
+                RequestMsg.ReturnValue = Status;
+                ReplyMsg = &RequestMsg;
+                break;
+        }
+    }
+    return STATUS_SUCCESS;
+}

Modified: trunk/reactos/base/system/smss2/smsessn.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smsessn.c?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smsessn.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smsessn.c [iso-8859-1] Tue Feb  7 07:13:42 
2012
@@ -25,12 +25,43 @@
 
 NTSTATUS
 NTAPI
+SmpGetProcessMuSessionId(IN HANDLE ProcessHandle,
+                         OUT PULONG SessionId)
+{
+    NTSTATUS Status;
+    ULONG ProcessSession;
+
+    /* Query the kernel for the session ID */
+    Status = NtQueryInformationProcess(ProcessHandle,
+                                       ProcessSessionInformation,
+                                       &ProcessSession,
+                                       sizeof(ProcessSession),
+                                       NULL);
+    if (NT_SUCCESS(Status))
+    {
+        /* Copy it back into the buffer */
+        *SessionId = ProcessSession;
+    }
+    else
+    {
+        /* Failure -- assume session zero */
+        DPRINT1("SMSS: GetProcessMuSessionId, Process=%x, Status=%x\n",
+                ProcessHandle, Status);
+        *SessionId = 0;
+    }
+    
+    /* Return result */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
 SmpSetProcessMuSessionId(IN HANDLE ProcessHandle,
                          IN ULONG SessionId)
 {
     NTSTATUS Status;
 
-    /* Tell the kernel about our session ID */
+    /* Tell the kernel about the session ID */
     Status = NtSetInformationProcess(ProcessHandle,
                                      ProcessSessionInformation,
                                      &SessionId,

Modified: trunk/reactos/base/system/smss2/smss.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smss.c?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smss.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smss.c [iso-8859-1] Tue Feb  7 07:13:42 2012
@@ -29,6 +29,8 @@
 UNICODE_STRING SmpSystemRoot;
 ULONG AttachedSessionId = -1;
 BOOLEAN SmpDebug, SmpEnableDots;
+HANDLE SmApiPort;
+HANDLE SmpInitialCommandProcessId;
 
 /* FUNCTIONS 
******************************************************************/
 
@@ -57,6 +59,7 @@
     NTSTATUS Status;
     RTL_USER_PROCESS_INFORMATION LocalProcessInfo;
     PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+    DPRINT1("Executing image: %wZ\n", FileName);
 
     /* Use the input process information if we have it, otherwise use local */
     ProcessInfo = ProcessInformation;
@@ -297,6 +300,103 @@
 
 NTSTATUS
 NTAPI
+SmpExecuteInitialCommand(IN ULONG MuSessionId,
+                         IN PUNICODE_STRING InitialCommand,
+                         IN HANDLE InitialCommandProcess,
+                         OUT PHANDLE ReturnPid)
+{
+    NTSTATUS Status;
+    RTL_USER_PROCESS_INFORMATION ProcessInfo;
+    UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName;
+    ULONG Flags = 0;
+
+    /* Check if we haven't yet connected to ourselves */
+    if (!SmApiPort)
+    {
+        /* Connect to ourselves, as a client */
+        Status = SmConnectToSm(0, 0, 0, &SmApiPort);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status);
+            return Status;
+        }
+    }
+
+    /* Parse the initial command line */
+    Status = SmpParseCommandLine(InitialCommand,
+                                 (PULONG)&Flags,
+                                 &ImageFileName,
+                                 &ImageFileDirectory,
+                                 &Arguments);
+    if (Flags & SMP_INVALID_PATH)
+    {
+        /* Fail if it doesn't exist */
+        DPRINT1("SMSS: Initial command image (%wZ) not found\n", 
&ImageFileName);
+        if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, 
ImageFileName.Buffer);
+        return STATUS_OBJECT_NAME_NOT_FOUND;
+    }
+
+    /* And fail if any other reason is also true */
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("SMSS: SmpParseCommand( %wZ ) failed - Status == %lx\n",
+                InitialCommand, Status);
+        return Status;
+    }
+
+    /* Execute the initial command -- but defer its full execution */
+    Status = SmpExecuteImage(&ImageFileName,
+                             &ImageFileDirectory,
+                             InitialCommand,
+                             MuSessionId,
+                             SMP_DEFERRED_FLAG,
+                             &ProcessInfo);
+
+    /* Free any buffers we had lying around */
+    if (ImageFileName.Buffer)
+    {
+        RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
+    }
+    if (ImageFileDirectory.Buffer)
+    {
+        RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer);
+    }
+    if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, 
Arguments.Buffer);
+
+    /* Bail out if we couldn't execute the initial command */
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Now duplicate the handle to this process */
+    Status = NtDuplicateObject(NtCurrentProcess(),
+                               ProcessInfo.ProcessHandle,
+                               NtCurrentProcess(),
+                               InitialCommandProcess,
+                               PROCESS_ALL_ACCESS,
+                               0,
+                               0);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Kill it utterly if duplication failed */
+        DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status);
+        NtTerminateProcess(ProcessInfo.ProcessHandle, Status);
+        NtResumeThread(ProcessInfo.ThreadHandle, NULL);
+        NtClose(ProcessInfo.ThreadHandle);
+        NtClose(ProcessInfo.ProcessHandle);
+        return Status;
+    }
+
+    /* Return PID to the caller, and set this as the initial command PID */
+    if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess;
+    if (!MuSessionId) SmpInitialCommandProcessId = 
ProcessInfo.ClientId.UniqueProcess;
+
+    /* Now call our server execution function to wrap up its initialization */
+    Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE);
+    if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == 
%lx\n", Status);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
 ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
                       OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
                       OUT PCHAR *ProcessEnvironment)
@@ -630,6 +730,9 @@
             DPRINT1("SMSS: SmpInit return failure - Status == %x\n", Status);
             RtlInitUnicodeString(&DbgString, L"Session Manager 
Initialization");
             Parameters[1] = Status;
+            DPRINT1("SMSS-2 Loaded... Launching original SMSS\n");
+            Status = LaunchOldSmss(Handles);
+            goto SetupHack;
             //_SEH2_LEAVE; Hack so that setup can work. will go away later
         }
 
@@ -647,14 +750,21 @@
             DPRINT1("Global Flags Set to SMSS Debugging: Not yet supported\n");
         }
 
-#if 0
-        /* Execute the initial command (Winlogon.exe) */
-        Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], 
NULL);
-#else
         /* Launch the original SMSS */
         DPRINT1("SMSS-2 Loaded... Launching original SMSS\n");
         Status = LaunchOldSmss(Handles);
-#endif
+        if (!NT_SUCCESS(Status))
+        {
+            /* Fail and raise a hard error */
+            DPRINT1("SMSS: Execute Old SMSS failed\n");
+            RtlInitUnicodeString(&DbgString,
+                                 L"Session Manager LaunchOldSmss");
+            Parameters[1] = Status;
+            _SEH2_LEAVE;
+        }
+        
+        /* Execute the initial command (Winlogon.exe) */
+        Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], 
NULL);
         if (!NT_SUCCESS(Status))
         {
             /* Fail and raise a hard error */
@@ -679,6 +789,7 @@
         SmpReleasePrivilege(State);
 
         /* Wait on either CSRSS or Winlogon to die */
+SetupHack:
         Status = NtWaitForMultipleObjects(RTL_NUMBER_OF(Handles),
                                           Handles,
                                           WaitAny,

Modified: trunk/reactos/base/system/smss2/smss.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smss.h?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smss.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smss.h [iso-8859-1] Tue Feb  7 07:13:42 2012
@@ -48,6 +48,20 @@
     UNICODE_STRING Value;
     PCHAR AnsiValue;
 } SMP_REGISTRY_VALUE, *PSMP_REGISTRY_VALUE;
+
+typedef struct _SMP_SUBSYSTEM
+{
+    LIST_ENTRY Entry;
+    HANDLE Event;
+    HANDLE ProcessHandle;
+    ULONG ImageType;
+    HANDLE PortHandle;
+    HANDLE SbApiPort;
+    CLIENT_ID ClientId;
+    ULONG MuSessionId;
+    BOOLEAN Terminating;
+    ULONG ReferenceCount;
+} SMP_SUBSYSTEM, *PSMP_SUBSYSTEM;
 
 /* EXTERNALS 
******************************************************************/
 
@@ -209,4 +223,31 @@
 SmpTranslateSystemPartitionInformation(
     VOID
 );
+
+PSMP_SUBSYSTEM
+NTAPI
+SmpLocateKnownSubSysByCid(
+    IN PCLIENT_ID ClientId
+);
+
+PSMP_SUBSYSTEM
+NTAPI
+SmpLocateKnownSubSysByType(
+    IN ULONG MuSessionId,
+    IN ULONG ImageType
+);
+
+NTSTATUS
+NTAPI
+SmpGetProcessMuSessionId(
+    IN HANDLE ProcessHandle,
+    OUT PULONG SessionId
+);
+
+VOID
+NTAPI
+SmpDereferenceSubsystem(
+    IN PSMP_SUBSYSTEM SubSystem
+);
+
 #endif

Modified: trunk/reactos/base/system/smss2/smss2.rbuild
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smss2.rbuild?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smss2.rbuild [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smss2.rbuild [iso-8859-1] Tue Feb  7 
07:13:42 2012
@@ -7,6 +7,7 @@
        <library>nt</library>
        <library>pseh</library>
        <library>ntdll</library>
+       <library>smlib</library>
        <pch>smss.h</pch>
        <compilationunit name="unit.c">
                <file>smss.c</file>

Modified: trunk/reactos/base/system/smss2/smsubsys.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smsubsys.c?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smsubsys.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smsubsys.c [iso-8859-1] Tue Feb  7 07:13:42 
2012
@@ -22,6 +22,97 @@
 WCHAR InitialCommandBuffer[256];
 
 /* FUNCTIONS 
******************************************************************/
+
+VOID
+NTAPI
+SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
+{
+    /* Acquire the database lock while we (potentially) destroy this subsystem 
*/
+    RtlEnterCriticalSection(&SmpKnownSubSysLock);
+
+    /* Drop the reference and see if it's terminating */
+    if (!(--SubSystem->ReferenceCount) && (SubSystem->Terminating))
+    {
+        /* Close all handles and free it */
+        if (SubSystem->Event) NtClose(SubSystem->Event);
+        if (SubSystem->ProcessHandle) NtClose(SubSystem->ProcessHandle);
+        if (SubSystem->SbApiPort) NtClose(SubSystem->SbApiPort);
+        RtlFreeHeap(SmpHeap, 0, SubSystem);
+    }
+
+    /* Release the database lock */
+    RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+}
+
+PSMP_SUBSYSTEM
+NTAPI
+SmpLocateKnownSubSysByCid(IN PCLIENT_ID ClientId)
+{
+    PSMP_SUBSYSTEM Subsystem = NULL;
+    PLIST_ENTRY NextEntry;
+
+    /* Lock the subsystem database */
+    RtlEnterCriticalSection(&SmpKnownSubSysLock);
+
+    /* Loop each subsystem in the database */
+    NextEntry = SmpKnownSubSysHead.Flink;
+    while (NextEntry != &SmpKnownSubSysHead)
+    {
+        /* Check if this one matches the client ID and is still valid */
+        Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
+        if ((*(PULONGLONG)&Subsystem->ClientId == *(PULONGLONG)&ClientId) &&
+            !(Subsystem->Terminating))
+        {
+            /* Add a reference and return it */
+            Subsystem->ReferenceCount++;
+            break;
+        }
+
+        /* Reset the current pointer and keep earching */
+        Subsystem = NULL;
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Release the lock and return the subsystem we found */
+    RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+    return Subsystem;
+}
+
+PSMP_SUBSYSTEM
+NTAPI
+SmpLocateKnownSubSysByType(IN ULONG MuSessionId,
+                           IN ULONG ImageType)
+{
+    PSMP_SUBSYSTEM Subsystem = NULL;
+    PLIST_ENTRY NextEntry;
+
+    /* Lock the subsystem database */
+    RtlEnterCriticalSection(&SmpKnownSubSysLock);
+
+    /* Loop each subsystem in the database */
+    NextEntry = SmpKnownSubSysHead.Flink;
+    while (NextEntry != &SmpKnownSubSysHead)
+    {
+        /* Check if this one matches the image and uID, and is still valid */
+        Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
+        if ((Subsystem->ImageType == ImageType) &&
+            !(Subsystem->Terminating) &&
+            (Subsystem->MuSessionId == MuSessionId))
+        {
+            /* Return it referenced for the caller */
+            Subsystem->ReferenceCount++;
+            break;
+        }
+
+        /* Reset the current pointer and keep earching */
+        Subsystem = NULL;
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Release the lock and return the subsystem we found */
+    RtlLeaveCriticalSection(&SmpKnownSubSysLock);
+    return Subsystem;
+}
 
 NTSTATUS
 NTAPI

Modified: trunk/reactos/include/reactos/subsys/sm/smmsg.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/sm/smmsg.h?rev=55478&r1=55477&r2=55478&view=diff
==============================================================================
--- trunk/reactos/include/reactos/subsys/sm/smmsg.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/subsys/sm/smmsg.h [iso-8859-1] Tue Feb  7 
07:13:42 2012
@@ -21,14 +21,14 @@
 //
 typedef enum _SMSRV_API_NUMBER
 {
-    SmpCreateForeignSession,
-    SmpSessionComplete,
-    SmpTerminateForeignSession,
-    SmpExecPgm,
-    SmpLoadDeferedSubsystem,
-    SmpStartCsr,
-    SmpStopCsr,
-    SmpMaxApiNumber // Based on BasepMaxApiNumber, UserpMaxApiNumber...
+    SmCreateForeignSessionApi,
+    SmSessionCompleteApi,
+    SmTerminateForeignSessionApi,
+    SmExecPgmApi,
+    SmLoadDeferedSubsystemApi,
+    SmStartCsrApi,
+    SmStopCsrApi,
+    SmMaxApiNumber // Based on BasepMaxApiNumber, UserpMaxApiNumber...
 } SMSRV_API_NUMBER;
 
 //
@@ -184,7 +184,7 @@
 //
 typedef struct _SB_API_MSG
 {
-    PORT_MESSAGE Header;
+    PORT_MESSAGE h;
     union
     {
         SB_CONNECTION_INFO ConnectionInfo;
@@ -208,4 +208,25 @@
 //
 C_ASSERT(sizeof(SB_CONNECTION_INFO) == 0xF4);
 C_ASSERT(sizeof(SB_API_MSG) == 0x110);
+
+//
+// The actual server functions that a client linking with smlib can call
+//
+NTSTATUS
+NTAPI
+SmConnectToSm(
+    IN PUNICODE_STRING SbApiPortName,
+    IN HANDLE SbApiPort,
+    IN ULONG ImageType,
+    IN HANDLE SmApiPort
+);
+
+NTSTATUS
+NTAPI
+SmExecPgm(
+    IN HANDLE SmApiPort,
+    IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
+    IN BOOLEAN DebugFlag
+);
+                        
 #endif


Reply via email to