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/CMakeLis…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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.…
==============================================================================
--- 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?r…
==============================================================================
--- 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?r…
==============================================================================
--- 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.rb…
==============================================================================
--- 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…
==============================================================================
--- 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/…
==============================================================================
--- 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