[SMSS]: Add a new SMSS2 with the goal of having a Windows-compatible LPC API that...
authorAlex Ionescu <aionescu@gmail.com>
Mon, 23 Jan 2012 16:49:52 +0000 (16:49 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Mon, 23 Jan 2012 16:49:52 +0000 (16:49 +0000)
svn path=/trunk/; revision=55123

reactos/base/system/CMakeLists.txt
reactos/base/system/smss2/CMakeLists.txt [new file with mode: 0644]
reactos/base/system/smss2/smss.c [new file with mode: 0644]
reactos/base/system/smss2/smss.h [new file with mode: 0644]
reactos/base/system/smss2/smss.rc [new file with mode: 0644]
reactos/base/system/smss2/smss2.rbuild [new file with mode: 0644]
reactos/base/system/system.rbuild
reactos/boot/bootdata/packages/reactos.dff
reactos/boot/bootdata/txtsetup.sif
reactos/ntoskrnl/ex/init.c

index eb3d25b..7bd0241 100644 (file)
@@ -13,6 +13,7 @@ add_subdirectory(rundll32)
 add_subdirectory(runonce)
 add_subdirectory(services)
 add_subdirectory(smss)
+add_subdirectory(smss2)
 add_subdirectory(subst)
 add_subdirectory(userinit)
 add_subdirectory(winlogon)
diff --git a/reactos/base/system/smss2/CMakeLists.txt b/reactos/base/system/smss2/CMakeLists.txt
new file mode 100644 (file)
index 0000000..273e5c8
--- /dev/null
@@ -0,0 +1,16 @@
+
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys)
+
+list(APPEND SOURCE
+    smss.c
+    smss.rc)
+
+add_executable(smss2 WIN32 ${SOURCE})
+
+target_link_libraries(smss2 nt)
+
+add_pch(smss2 smss.h)
+
+set_module_type(smss2 nativecui)
+add_importlibs(smss2 ntdll)
+add_cd_file(TARGET smss2 DESTINATION reactos/system32 NO_CAB FOR all)
diff --git a/reactos/base/system/smss2/smss.c b/reactos/base/system/smss2/smss.c
new file mode 100644 (file)
index 0000000..c880a17
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * PROJECT:         ReactOS Windows-Compatible Session Manager
+ * LICENSE:         BSD 2-Clause License
+ * FILE:            base/system/smss/smss.c
+ * PURPOSE:         Main SMSS Code
+ * PROGRAMMERS:     Alex Ionescu
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "smss.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS ********************************************************************/
+
+typedef struct _INIT_BUFFER
+{
+    WCHAR DebugBuffer[256];
+    RTL_USER_PROCESS_INFORMATION ProcessInfo;
+} INIT_BUFFER, *PINIT_BUFFER;
+
+/* NT Initial User Application */
+WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss.exe";
+ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) -
+                                         sizeof(WCHAR);
+ULONG NtInitialUserProcessBufferType = REG_SZ;
+
+UNICODE_STRING NtSystemRoot;
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
+                      OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
+                      OUT PCHAR *ProcessEnvironment)
+{
+    NTSTATUS Status;
+    SIZE_T Size;
+    PWSTR p;
+    UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
+    UNICODE_STRING SmssName, Environment, SystemDriveString, DebugString;
+    PVOID EnvironmentPtr = NULL;
+    PRTL_USER_PROCESS_INFORMATION ProcessInformation;
+    PRTL_USER_PROCESS_PARAMETERS ProcessParams = NULL;
+
+    NullString.Length = sizeof(WCHAR);
+
+    /* Use the initial buffer, after the strings */
+    ProcessInformation = &InitBuffer->ProcessInfo;
+
+    /* Allocate memory for the process parameters */
+    Size = sizeof(*ProcessParams) + ((MAX_PATH * 6) * sizeof(WCHAR));
+    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                     (PVOID*)&ProcessParams,
+                                     0,
+                                     &Size,
+                                     MEM_COMMIT,
+                                     PAGE_READWRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to allocate Process Parameters. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
+        return Status;
+    }
+
+    /* Setup the basic header, and give the process the low 1MB to itself */
+    ProcessParams->Length = (ULONG)Size;
+    ProcessParams->MaximumLength = (ULONG)Size;
+    ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |
+                           RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
+
+    /* Allocate a page for the environment */
+    Size = PAGE_SIZE;
+    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                     &EnvironmentPtr,
+                                     0,
+                                     &Size,
+                                     MEM_COMMIT,
+                                     PAGE_READWRITE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to allocate Process Environment. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
+        return Status;
+    }
+
+    /* Write the pointer */
+    ProcessParams->Environment = EnvironmentPtr;
+
+    /* Make a buffer for the DOS path */
+    p = (PWSTR)(ProcessParams + 1);
+    ProcessParams->CurrentDirectory.DosPath.Buffer = p;
+    ProcessParams->CurrentDirectory.DosPath.MaximumLength = MAX_PATH *
+                                                            sizeof(WCHAR);
+
+    /* Copy the DOS path */
+    RtlCopyUnicodeString(&ProcessParams->CurrentDirectory.DosPath,
+                         &NtSystemRoot);
+
+    /* Make a buffer for the DLL Path */
+    p = (PWSTR)((PCHAR)ProcessParams->CurrentDirectory.DosPath.Buffer +
+                ProcessParams->CurrentDirectory.DosPath.MaximumLength);
+    ProcessParams->DllPath.Buffer = p;
+    ProcessParams->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+    /* Copy the DLL path and append the system32 directory */
+    RtlCopyUnicodeString(&ProcessParams->DllPath,
+                         &ProcessParams->CurrentDirectory.DosPath);
+    RtlAppendUnicodeToString(&ProcessParams->DllPath, L"\\System32");
+
+    /* Make a buffer for the image name */
+    p = (PWSTR)((PCHAR)ProcessParams->DllPath.Buffer +
+                ProcessParams->DllPath.MaximumLength);
+    ProcessParams->ImagePathName.Buffer = p;
+    ProcessParams->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+    /* Make sure the buffer is a valid string which within the given length */
+    if ((NtInitialUserProcessBufferType != REG_SZ) ||
+        ((NtInitialUserProcessBufferLength != MAXULONG) &&
+         ((NtInitialUserProcessBufferLength < sizeof(WCHAR)) ||
+          (NtInitialUserProcessBufferLength >
+           sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR)))))
+    {
+        /* Invalid initial process string, bugcheck */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Cut out anything after a space */
+    p = NtInitialUserProcessBuffer;
+    while ((*p) && (*p != L' ')) p++;
+
+    /* Set the image path length */
+    ProcessParams->ImagePathName.Length =
+        (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer);
+
+    /* Copy the actual buffer */
+    RtlCopyMemory(ProcessParams->ImagePathName.Buffer,
+                  NtInitialUserProcessBuffer,
+                  ProcessParams->ImagePathName.Length);
+
+    /* Null-terminate it */
+    ProcessParams->ImagePathName.Buffer[ProcessParams->ImagePathName.Length /
+                                        sizeof(WCHAR)] = UNICODE_NULL;
+
+    /* Make a buffer for the command line */
+    p = (PWSTR)((PCHAR)ProcessParams->ImagePathName.Buffer +
+                ProcessParams->ImagePathName.MaximumLength);
+    ProcessParams->CommandLine.Buffer = p;
+    ProcessParams->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+    /* Add the image name to the command line */
+    RtlAppendUnicodeToString(&ProcessParams->CommandLine,
+                             NtInitialUserProcessBuffer);
+
+    /* Create the environment string */
+    RtlInitEmptyUnicodeString(&Environment,
+                              ProcessParams->Environment,
+                              (USHORT)Size);
+
+    /* Append the DLL path to it */
+    RtlAppendUnicodeToString(&Environment, L"Path=" );
+    RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath);
+    RtlAppendUnicodeStringToString(&Environment, &NullString);
+
+    /* Create the system drive string */
+    SystemDriveString = NtSystemRoot;
+    SystemDriveString.Length = 2 * sizeof(WCHAR);
+
+    /* Append it to the environment */
+    RtlAppendUnicodeToString(&Environment, L"SystemDrive=");
+    RtlAppendUnicodeStringToString(&Environment, &SystemDriveString);
+    RtlAppendUnicodeStringToString(&Environment, &NullString);
+
+    /* Append the system root to the environment */
+    RtlAppendUnicodeToString(&Environment, L"SystemRoot=");
+    RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
+    RtlAppendUnicodeStringToString(&Environment, &NullString);
+
+    /* Create SMSS process */
+    SmssName = ProcessParams->ImagePathName;
+    Status = RtlCreateUserProcess(&SmssName,
+                                  OBJ_CASE_INSENSITIVE,
+                                  RtlDeNormalizeProcessParams(ProcessParams),
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  FALSE,
+                                  NULL,
+                                  NULL,
+                                  ProcessInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to create Session Manager. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
+        return Status;
+    }
+
+    /* Resume the thread */
+    Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to resume Session Manager. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
+        return Status;
+    }
+
+    /* Return success */
+    *ProcessParameters = ProcessParams;
+    *ProcessEnvironment = EnvironmentPtr;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+LaunchOldSmss(VOID)
+{
+    PINIT_BUFFER InitBuffer;
+    PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
+    PRTL_USER_PROCESS_INFORMATION ProcessInfo;
+    LARGE_INTEGER Timeout;
+    NTSTATUS Status;
+    PCHAR Environment;
+    SIZE_T Size;
+  
+    /* Setup system root */
+    RtlInitUnicodeString(&NtSystemRoot, SharedUserData->NtSystemRoot);
+   
+    /* Allocate the initialization buffer */
+    InitBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(INIT_BUFFER));
+    if (!InitBuffer)
+    {
+        /* Bugcheck */
+        return STATUS_NO_MEMORY;
+    }
+   
+    /* Launch initial process */
+    ProcessInfo = &InitBuffer->ProcessInfo;
+    Status = ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Failed, display error */
+        DPRINT1("INIT: Session Manager failed to load.\n");
+        return Status;
+    }
+
+    /* Wait 5 seconds for initial process to initialize */
+    Timeout.QuadPart = Int32x32To64(5, -10000000);
+    Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout);
+    if (Status == STATUS_SUCCESS)
+    {
+        /* Failed, display error */
+        DPRINT1("INIT: Session Manager terminated.\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Close process handles */
+    ZwClose(ProcessInfo->ThreadHandle);
+    ZwClose(ProcessInfo->ProcessHandle);
+
+    /* Free the initial process environment */
+    Size = 0;
+    ZwFreeVirtualMemory(NtCurrentProcess(),
+                        (PVOID*)&Environment,
+                        &Size,
+                        MEM_RELEASE);
+
+    /* Free the initial process parameters */
+    Size = 0;
+    ZwFreeVirtualMemory(NtCurrentProcess(),
+                        (PVOID*)&ProcessParameters,
+                        &Size,
+                        MEM_RELEASE);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+__cdecl
+_main(IN INT argc,
+      IN PCHAR argv[],
+      IN PCHAR envp[],
+      IN ULONG DebugFlag)
+{
+    NTSTATUS Status;
+    
+    /* Launch the original SMSS */
+    DPRINT1("SMSS-2 Loaded... Launching original SMSS\n");
+    Status = LaunchOldSmss();
+
+    /* Terminate this SMSS for now, later we'll have an LPC thread running */
+    return NtTerminateThread(NtCurrentThread(), Status);
+}
+
+/* EOF */
diff --git a/reactos/base/system/smss2/smss.h b/reactos/base/system/smss2/smss.h
new file mode 100644 (file)
index 0000000..8244485
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once
+
+#define WIN32_NO_STATUS
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
diff --git a/reactos/base/system/smss2/smss.rc b/reactos/base/system/smss2/smss.rc
new file mode 100644 (file)
index 0000000..98ad190
--- /dev/null
@@ -0,0 +1,4 @@
+#define REACTOS_STR_FILE_DESCRIPTION     "ReactOS Session Manager\0"
+#define REACTOS_STR_INTERNAL_NAME        "smss\0"
+#define REACTOS_STR_ORIGINAL_FILENAME    "smss.exe\0"
+#include <reactos/version.rc>
diff --git a/reactos/base/system/smss2/smss2.rbuild b/reactos/base/system/smss2/smss2.rbuild
new file mode 100644 (file)
index 0000000..a48cc56
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="smss2" type="nativecui" installbase="system32" installname="smss2.exe">
+       <bootstrap installbase="$(CDOUTPUT)/system32" />
+       <include base="smss2">.</include>
+       <include base="ReactOS">include/reactos/subsys</include>
+       <library>nt</library>
+       <library>ntdll</library>
+       <pch>smss.h</pch>
+       <compilationunit name="unit.c">
+               <file>smss.c</file>
+       </compilationunit>
+       <file>smss.rc</file>
+</module>
index 885021c..dd34b38 100644 (file)
@@ -40,6 +40,9 @@
        <directory name="smss">
                <xi:include href="smss/smss.rbuild" />
        </directory>
+       <directory name="smss2">
+               <xi:include href="smss2/smss2.rbuild" />
+       </directory>
        <directory name="userinit">
                <xi:include href="userinit/userinit.rbuild" />
        </directory>
index 2212786..a9aba36 100644 (file)
@@ -128,6 +128,7 @@ base\system\rundll32\rundll32.exe                   1
 base\system\runonce\runonce.exe                     1
 base\system\services\services.exe                   1
 base\system\smss\smss.exe                           1
+base\system\smss2\smss2.exe                         1
 base\system\userinit\userinit.exe                   1
 base\system\winlogon\winlogon.exe                   1
 
index 1c0ca8d..1b7f1c7 100644 (file)
@@ -48,6 +48,7 @@ pcix.sys=,,,,,,,,,,,,4
 pcmcia.sys=,,,,,,,,,,,,4
 swenum.sys=,,,,,,,,,,,,4
 ntdll.dll=,,,,,,,,,,,,2
+smss2.exe=,,,,,,,,,,,,2
 
 [HardwareIdsDatabase]
 ;*PNP0A00 = isapnp
index 90c2bfa..5b16e20 100644 (file)
@@ -66,7 +66,7 @@ BOOLEAN InitIsWinPEMode, InitWinPEModeType;
 UNICODE_STRING NtSystemRoot;
 
 /* NT Initial User Application */
-WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss.exe";
+WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss2.exe";
 ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) -
                                          sizeof(WCHAR);
 ULONG NtInitialUserProcessBufferType = REG_SZ;