Author: ion
Date: Thu Feb  9 00:07:36 2012
New Revision: 55508

URL: http://svn.reactos.org/svn/reactos?rev=55508&view=rev
Log:
[SMSS2]: Implement SmpExecPgm and SmpSbCreateSession. Nothing happens 
(STATUS_OBJECT_NAME_NOT_FOUND is returned) because we don't really launch CSRSS 
and so we can't find a subsystem for Winlogon and fail (as expected for now).

Modified:
    trunk/reactos/base/system/smss2/smloop.c
    trunk/reactos/base/system/smss2/smsbapi.c

Modified: trunk/reactos/base/system/smss2/smloop.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smloop.c?rev=55508&r1=55507&r2=55508&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smloop.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smloop.c [iso-8859-1] Thu Feb  9 00:07:36 
2012
@@ -71,8 +71,69 @@
            IN PSMP_CLIENT_CONTEXT ClientContext,
            IN HANDLE SmApiPort)
 {
-    DPRINT1("%s is not yet implemented\n", __FUNCTION__);
-    return STATUS_NOT_IMPLEMENTED;
+    HANDLE ProcessHandle;
+    NTSTATUS Status;
+    PSM_EXEC_PGM_MSG SmExecPgm;
+    RTL_USER_PROCESS_INFORMATION ProcessInformation;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+
+    /* Open the client process */
+    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+    Status = NtOpenProcess(&ProcessHandle,
+                           PROCESS_DUP_HANDLE,
+                           &ObjectAttributes,
+                           &SmApiMsg->h.ClientId);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        DPRINT1("SmExecPgm: NtOpenProcess Failed %lx\n", Status);
+        return Status;
+    }
+
+    /* Copy the process information out of the message */
+    SmExecPgm = &SmApiMsg->u.ExecPgm;
+    ProcessInformation = SmExecPgm->ProcessInformation;
+
+    /* Duplicate the process handle */
+    Status = NtDuplicateObject(ProcessHandle,
+                               SmExecPgm->ProcessInformation.ProcessHandle,
+                               NtCurrentProcess(),
+                               &ProcessInformation.ProcessHandle,
+                               PROCESS_ALL_ACCESS,
+                               0,
+                               0);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Close the handle and fail */
+        NtClose(ProcessHandle);
+        DPRINT1("SmExecPgm: NtDuplicateObject (Process) Failed %lx\n", Status);
+        return Status;
+    }
+
+    /* Duplicate the thread handle */
+    Status = NtDuplicateObject(ProcessHandle,
+                               SmExecPgm->ProcessInformation.ThreadHandle,
+                               NtCurrentProcess(),
+                               &ProcessInformation.ThreadHandle,
+                               THREAD_ALL_ACCESS,
+                               0,
+                               0);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Close both handles and fail */
+        NtClose(ProcessInformation.ProcessHandle);
+        NtClose(ProcessHandle);
+        DPRINT1("SmExecPgm: NtDuplicateObject (Thread) Failed %lx\n", Status);
+        return Status;
+    }
+
+    /* Close the process handle and call the internal client API */
+    NtClose(ProcessHandle);
+    return SmpSbCreateSession(NULL,
+                              NULL,
+                              &ProcessInformation,
+                              0,
+                              SmExecPgm->DebugFlag ? &SmApiMsg->h.ClientId : 
NULL);
 }
 
 NTSTATUS

Modified: trunk/reactos/base/system/smss2/smsbapi.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss2/smsbapi.c?rev=55508&r1=55507&r2=55508&view=diff
==============================================================================
--- trunk/reactos/base/system/smss2/smsbapi.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss2/smsbapi.c [iso-8859-1] Thu Feb  9 00:07:36 
2012
@@ -14,4 +14,173 @@
 
 /* GLOBALS 
********************************************************************/
 
+PCHAR SmpSubSystemNames[] =
+{
+    "Unknown",
+    "Native",
+    "Windows",
+    "Posix",
+    "OS/2"
+};
+
 /* FUNCTIONS 
******************************************************************/
+
+NTSTATUS
+NTAPI
+SmpSbCreateSession(IN PVOID Reserved,
+                   IN PSMP_SUBSYSTEM OtherSubsystem,
+                   IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
+                   IN ULONG MuSessionId,
+                   IN PCLIENT_ID DbgClientId)
+{
+    NTSTATUS Status;
+    PSMP_SUBSYSTEM KnownSubsys;
+    SB_API_MSG SbApiMsg;
+    ULONG SessionId;
+    PSB_CREATE_SESSION_MSG CreateSessionMsg;
+
+    /* Write out the create session message including its initial process */
+    CreateSessionMsg = &SbApiMsg.CreateSession;
+    CreateSessionMsg->ProcessInfo = *ProcessInformation;
+    CreateSessionMsg->MuSessionId = MuSessionId;
+    if (DbgClientId)
+    {
+        CreateSessionMsg->ClientId = *DbgClientId;
+    }
+    else
+    {
+        CreateSessionMsg->ClientId.UniqueThread = NULL;
+        CreateSessionMsg->ClientId.UniqueProcess = NULL;
+    }
+
+    /* Find a subsystem responsible for this session */
+    SmpGetProcessMuSessionId(ProcessInformation->ProcessHandle, &MuSessionId);
+    if (!SmpCheckDuplicateMuSessionId(MuSessionId))
+    {
+        NtClose(ProcessInformation->ProcessHandle);
+        NtClose(ProcessInformation->ThreadHandle);
+        DPRINT1("SMSS: CreateSession status=%x\n", 
STATUS_OBJECT_NAME_NOT_FOUND);
+        return STATUS_OBJECT_NAME_NOT_FOUND;
+    }
+
+    /* Find the subsystem we have for this initial process */
+    KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId,
+                                             ProcessInformation->
+                                             ImageInformation.SubSystemType);
+    if (KnownSubsys)
+    {
+        /* Duplicate the process handle into the message */
+        Status = NtDuplicateObject(NtCurrentProcess(),
+                                   ProcessInformation->ProcessHandle,
+                                   KnownSubsys->ProcessHandle,
+                                   
&CreateSessionMsg->ProcessInfo.ProcessHandle,
+                                   PROCESS_ALL_ACCESS,
+                                   0,
+                                   0);
+        if (NT_SUCCESS(Status))
+        {
+            /* Duplicate the thread handle into the message */
+            Status = NtDuplicateObject(NtCurrentProcess(),
+                                       ProcessInformation->ThreadHandle,
+                                       KnownSubsys->ProcessHandle,
+                                       
&CreateSessionMsg->ProcessInfo.ThreadHandle,
+                                       THREAD_ALL_ACCESS,
+                                       0,
+                                       0);
+            if (!NT_SUCCESS(Status))
+            {
+                /* Close everything on failure */
+                NtClose(ProcessInformation->ProcessHandle);
+                NtClose(ProcessInformation->ThreadHandle);
+                SmpDereferenceSubsystem(KnownSubsys);
+                DbgPrint("SmpSbCreateSession: NtDuplicateObject (Thread) 
Failed %lx\n", Status);
+                return Status;
+            }
+
+            /* Close the original handles as they are no longer needed */
+            NtClose(ProcessInformation->ProcessHandle);
+            NtClose(ProcessInformation->ThreadHandle);
+
+            /* Finally, allocate a new SMSS session ID for this session */
+            SessionId = SmpAllocateSessionId(KnownSubsys, OtherSubsystem);
+            CreateSessionMsg->SessionId = SessionId;
+
+            /* Fill out the LPC message header and send it to the client! */
+            SbApiMsg.ApiNumber = SbpCreateSession;
+            SbApiMsg.h.u2.ZeroInit = 0;
+            SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
+            SbApiMsg.h.u1.s1.TotalLength = sizeof(SbApiMsg);
+            Status = NtRequestWaitReplyPort(KnownSubsys->SbApiPort,
+                                            &SbApiMsg.h,
+                                            &SbApiMsg.h);
+            if (!NT_SUCCESS(Status))
+            {
+                /* Bail out */
+                DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", 
Status);
+            }
+            else
+            {
+                /* If the API succeeded, get the result value from the LPC */
+                Status = SbApiMsg.ReturnValue;
+            }
+
+            /* Delete the session on any kind of failure */
+            if (!NT_SUCCESS(Status)) SmpDeleteSession(SessionId);
+        }
+        else
+        {
+            /* Close the handles on failure */
+            DPRINT1("SmpSbCreateSession: NtDuplicateObject (Process) Failed 
%lx\n", Status);
+            NtClose(ProcessInformation->ProcessHandle);
+            NtClose(ProcessInformation->ThreadHandle);
+        }
+
+        /* Dereference the subsystem and return the status of the LPC call */
+        SmpDereferenceSubsystem(KnownSubsys);
+        return Status;
+    }
+
+    /* If we don't yet have a subsystem, only native images can be launched */
+    if (ProcessInformation->ImageInformation.SubSystemType != 
IMAGE_SUBSYSTEM_NATIVE)
+    {
+        /* Fail */
+        DPRINT1("SMSS: %s SubSystem has not been started.\n",
+                
SmpSubSystemNames[ProcessInformation->ImageInformation.SubSystemType]);
+        Status = STATUS_UNSUCCESSFUL;
+        NtClose(ProcessInformation->ProcessHandle);
+        NtClose(ProcessInformation->ThreadHandle);
+        return Status;
+    }
+
+#if 0
+    /* This code handles debug applications, but it seems vestigial... */
+    if ((*(ULONGLONG)&CreateSessionMsg.ClientId) && (SmpDbgSsLoaded))
+    {
+        Process = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_PROCESS));
+        if (!Process)
+        {
+            DPRINT1("Unable to initialize debugging for Native App %lx.%lx -- 
out of memory\n",
+                    ProcessInformation->ClientId.UniqueProcess,
+                    ProcessInformation->ClientId.UniqueThread);
+            NtClose(ProcessInformation->ProcessHandle);
+            NtClose(ProcessInformation->ThreadHandle);
+            return STATUS_NO_MEMORY;
+        }
+
+        Process->DbgClientId = CreateSessionMsg->ClientId;
+        Process->ClientId = ProcessInformation->ClientId;
+        InsertHeadList(&NativeProcessList, &Process->Entry);
+        DPRINT1("Native Debug App %lx.%lx\n", Process->ClientId.UniqueProcess, 
Process->ClientId.UniqueThread);
+
+        Status = NtSetInformationProcess(ProcessInformation->ProcessHandle, 7, 
&SmpDebugPort, 4);
+        ASSERT(NT_SUCCESS(Status));
+    }
+#endif
+
+    /* This is a native application being started as the initial command */
+    DPRINT1("Subsystem active, starting thread\n");
+    NtClose(ProcessInformation->ProcessHandle);
+    NtResumeThread(ProcessInformation->ThreadHandle, NULL);
+    NtClose(ProcessInformation->ThreadHandle);
+    return STATUS_SUCCESS;
+}


Reply via email to