SM: change the way sessions are managed. (it may be buggy) Modified: trunk/reactos/subsys/smss/client.c Modified: trunk/reactos/subsys/smss/initmv.c Modified: trunk/reactos/subsys/smss/initrun.c Modified: trunk/reactos/subsys/smss/initss.c Modified: trunk/reactos/subsys/smss/smapi.c Modified: trunk/reactos/subsys/smss/smapicomp.c Modified: trunk/reactos/subsys/smss/smapiexec.c Modified: trunk/reactos/subsys/smss/smss.c Modified: trunk/reactos/subsys/smss/smss.h _____
Modified: trunk/reactos/subsys/smss/client.c --- trunk/reactos/subsys/smss/client.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/client.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -39,9 +39,11 @@
RTL_CRITICAL_SECTION Lock; ULONG Count; PSM_CLIENT_DATA Client; + PSM_CLIENT_DATA CandidateClient;
} SmpClientDirectory;
+ /********************************************************************** * SmInitializeClientManagement/0 */ @@ -52,56 +54,41 @@ RtlInitializeCriticalSection(& SmpClientDirectory.Lock); SmpClientDirectory.Count = 0; SmpClientDirectory.Client = NULL; + SmpClientDirectory.CandidateClient = NULL; return STATUS_SUCCESS;
} - /********************************************************************** - * SmCompleteClientInitialization/1 - * - * DESCRIPTION - * Lookup the subsystem server descriptor given the process handle - * of the subsystem server process. + * SmpSetClientInitialized/1 */ -NTSTATUS STDCALL -SmCompleteClientInitialization (HANDLE hProcess) +VOID FASTCALL +SmpSetClientInitialized (PSM_CLIENT_DATA Client) { - NTSTATUS Status = STATUS_SUCCESS; - PSM_CLIENT_DATA Client = NULL; - - DPRINT("SM: %s called\n", __FUNCTION__); - - RtlEnterCriticalSection (& SmpClientDirectory.Lock); - if (SmpClientDirectory.Count > 0) - { - Client = SmpClientDirectory.Client; - while (NULL != Client) - { - if (hProcess == Client->ServerProcess) - { - Client->Initialized = TRUE; - break; - } - Client = Client->Next; - } - Status = STATUS_NOT_FOUND; - } - RtlLeaveCriticalSection (& SmpClientDirectory.Lock); - return Status; + Client->Flags |= SM_CLIENT_FLAG_INITIALIZED; } - /********************************************************************** - * SmpLookupClient/1 PRIVATE + * SmpLookupClient/2 PRIVATE * * DESCRIPTION * Lookup the subsystem server descriptor given its image ID. * - * SIDE EFFECTS - * SmpClientDirectory.Lock is released only on success. + * ARGUMENTS + * SubsystemId: IMAGE_SUBSYSTEM_xxx + * Parent: optional: caller provided storage for the + * the pointer to the SM_CLIENT_DATA which + * Next field contains the value returned by + * the function (on success). + * + * RETURN VALUES + * NULL on error; otherwise a pointer to the SM_CLIENT_DATA + * looked up object. + * + * WARNING + * SmpClientDirectory.Lock must be held by the caller. */ static PSM_CLIENT_DATA FASTCALL -SmpLookupClientUnsafe (USHORT SubsystemId, - PSM_CLIENT_DATA * Parent) +SmpLookupClient (USHORT SubsystemId, + PSM_CLIENT_DATA * Parent) { PSM_CLIENT_DATA Client = NULL;
@@ -129,72 +116,86 @@ } return Client; } - -static PSM_CLIENT_DATA STDCALL -SmpLookupClient (USHORT SubsystemId) -{ - PSM_CLIENT_DATA Client = NULL; - - DPRINT("SM: %s called\n", __FUNCTION__); - - RtlEnterCriticalSection (& SmpClientDirectory.Lock); - Client = SmpLookupClientUnsafe (SubsystemId, NULL); - if(NULL != Client) - { - RtlLeaveCriticalSection (& SmpClientDirectory.Lock); - } - /* - * Note that we do *not* release SmpClientDirectory.Lock here - * because SmpLookupClient is called to FAIL when SubsystemId - * is not registered yet. - */ - return Client; -} - /********************************************************************** - * SmpCreateClient/2 + * SmBeginClientInitialization/1 + * + * DESCRIPTION + * Check if the candidate client matches the begin session + * message from the subsystem process. + * + * ARGUMENTS + * Request: message received by \SmApiPort + * ClientData: + * + * RETURN VALUES + * NTSTATUS */ NTSTATUS STDCALL -SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData) +SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request, + OUT PSM_CLIENT_DATA * ClientData) { - PSM_CLIENT_DATA pClient = NULL; + NTSTATUS Status = STATUS_SUCCESS; PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request); ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);
+ DPRINT("SM: %s called\n", __FUNCTION__); - + + RtlEnterCriticalSection (& SmpClientDirectory.Lock); /* + * Is there a subsystem bootstrap in progress? + */ + if (SmpClientDirectory.CandidateClient) + { + PROCESS_BASIC_INFORMATION pbi; + + RtlZeroMemory (& pbi, sizeof pbi); + Status = NtQueryInformationProcess (Request->Header.ClientId.UniqueProcess, + ProcessBasicInformation, + & pbi, + sizeof pbi, + NULL); + if (NT_SUCCESS(Status)) + { + SmpClientDirectory.CandidateClient->ServerProcessId = + (ULONG) pbi.UniqueProcessId; + } + } + else + { + RtlFreeHeap (SmpHeap, 0, SmpClientDirectory.CandidateClient); + DPRINT1("SM: %s: subsys booting with no descriptor!\n", __FUNCTION__); + Status = STATUS_NOT_FOUND; + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + return Status; + } + /* * Check if a client for the ID already exist. */ - if (SmpLookupClient(ConnectData->SubSystemId)) + if (SmpLookupClient(ConnectData->SubSystemId, NULL)) { DPRINT("SM: %s: attempt to register again subsystem %d.\n", __FUNCTION__, ConnectData->SubSystemId); return STATUS_UNSUCCESSFUL; } - DPRINT("SM: %s: registering subsystem ID=%d \n", __FUNCTION__, ConnectData->SubSystemId); + DPRINT("SM: %s: registering subsystem ID=%d \n", + __FUNCTION__, ConnectData->SubSystemId); + /* - * Allocate the storage for client data + * Initialize the client data */ - pClient = RtlAllocateHeap (SmpHeap, - HEAP_ZERO_MEMORY, - sizeof (SM_CLIENT_DATA)); - if (NULL == pClient) + SmpClientDirectory.CandidateClient->SubsystemId = ConnectData->SubSystemId; + /* SM && DBG auto-initializes; other subsystems are required to call + * SM_API_COMPLETE_SESSION via SMDLL. */ + if ((IMAGE_SUBSYSTEM_NATIVE == SmpClientDirectory.CandidateClient->SubsystemId) || + (IMAGE_SUBSYSTEM_UNKNOWN == SmpClientDirectory.CandidateClient->SubsystemId)) { - DPRINT("SM: %s: out of memory!\n",__FUNCTION__); - return STATUS_NO_MEMORY; + SmpSetClientInitialized (SmpClientDirectory.CandidateClient); } - /* - * Initialize the client data - */ - pClient->SubsystemId = ConnectData->SubSystemId; - /* SM auto-initializes; other subsystems are required to call - * SM_API_COMPLETE_SESSION via SMDLL. */ - pClient->Initialized = (IMAGE_SUBSYSTEM_NATIVE == pClient->SubsystemId); if (SbApiPortNameSize > 0) { - RtlCopyMemory (pClient->SbApiPortName, + RtlCopyMemory (SmpClientDirectory.CandidateClient->SbApiPortName, ConnectData->SbName, SbApiPortNameSize); } @@ -204,30 +205,134 @@ */ if (NULL == SmpClientDirectory.Client) { - SmpClientDirectory.Client = pClient; + SmpClientDirectory.Client = SmpClientDirectory.CandidateClient; } else { PSM_CLIENT_DATA pCD = NULL;
for (pCD=SmpClientDirectory.Client; (NULL != pCD->Next); pCD = pCD->Next); - pCD->Next = pClient; + pCD->Next = SmpClientDirectory.CandidateClient; } - pClient->Next = NULL; + SmpClientDirectory.CandidateClient->Next = NULL; + /* + * Increment the number of active subsystems. + */ ++ SmpClientDirectory.Count; /* - * Note we unlock the client directory here, because - * it was locked by SmpLookupClient on failure. + * Notify to the caller the reference to the client data. */ - RtlLeaveCriticalSection (& SmpClientDirectory.Lock); if (ClientData) { - *ClientData = pClient; + *ClientData = SmpClientDirectory.CandidateClient; } + /* + * Free the slot for the candidate subsystem. + */ + SmpClientDirectory.CandidateClient = NULL; + + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + return STATUS_SUCCESS; } +/********************************************************************** + * SmCompleteClientInitialization/1 + * + * DESCRIPTION + * Lookup the subsystem server descriptor given the process ID + * of the subsystem server process. + */ +NTSTATUS STDCALL +SmCompleteClientInitialization (ULONG ProcessId) +{ + NTSTATUS Status = STATUS_SUCCESS; + PSM_CLIENT_DATA Client = NULL;
+ DPRINT("SM: %s called\n", __FUNCTION__); + + RtlEnterCriticalSection (& SmpClientDirectory.Lock); + if (SmpClientDirectory.Count > 0) + { + Client = SmpClientDirectory.Client; + while (NULL != Client) + { + if (ProcessId == Client->ServerProcessId) + { + SmpSetClientInitialized (Client); + break; + } + Client = Client->Next; + } + Status = STATUS_NOT_FOUND; + } + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + return Status; +} + /********************************************************************** + * SmpCreateClient/1 + * + * DESCRIPTION + * Create a "candidate" client. Client descriptor will enter the + * client directory only at the end of the registration + * procedure. Otherwise, we will kill the associated process. + * + * ARGUMENTS + * ProcessHandle: handle of the subsystem server process. + * + * RETURN VALUE + * NTSTATUS: + */ +NTSTATUS STDCALL +SmCreateClient (PRTL_PROCESS_INFO ProcessInfo, PWSTR ProgramName) +{ + NTSTATUS Status = STATUS_SUCCESS; + + + DPRINT("SM: %s(%lx) called\n", __FUNCTION__, ProcessInfo->ProcessHandle); + RtlEnterCriticalSection (& SmpClientDirectory.Lock); + /* + * Check if the candidate client slot is empty. + */ + if (NULL != SmpClientDirectory.CandidateClient) + { + DPRINT1("SM: %s: CandidateClient pending!\n", __FUNCTION__); + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + return STATUS_UNSUCCESSFUL; + } + /* + * Allocate the storage for client data + */ + SmpClientDirectory.CandidateClient = + RtlAllocateHeap (SmpHeap, + HEAP_ZERO_MEMORY, + sizeof (SM_CLIENT_DATA)); + if (NULL == SmpClientDirectory.CandidateClient) + { + DPRINT("SM: %s(%lx): out of memory!\n", + __FUNCTION__, ProcessInfo->ProcessHandle); + Status = STATUS_NO_MEMORY; + } + else + { + /* Initialize the candidate client. */ + RtlInitializeCriticalSection(& SmpClientDirectory.CandidateClient->Lock); + SmpClientDirectory.CandidateClient->ServerProcess = + (HANDLE) ProcessInfo->ProcessHandle; + SmpClientDirectory.CandidateClient->ServerProcessId = + (ULONG) ProcessInfo->ClientId.UniqueProcess; + } + /* + * Copy the program name + */ + RtlCopyMemory (SmpClientDirectory.CandidateClient->ProgramName, + ProgramName, + SM_SB_NAME_MAX_LENGTH); + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + return Status; +} + +/********************************************************************** * SmpDestroyClient/1 * * 1. close any handle @@ -244,7 +349,7 @@ DPRINT("SM: %s called\n", __FUNCTION__);
RtlEnterCriticalSection (& SmpClientDirectory.Lock); - Client = SmpLookupClientUnsafe (SubsystemId, & Parent); + Client = SmpLookupClient (SubsystemId, & Parent); if(NULL == Client) { DPRINT1("SM: %s: del req for non existent subsystem (id=%d)\n", @@ -269,6 +374,7 @@ } } /* TODO: send shutdown or kill */ + NtTerminateProcess (Client->ServerProcess, 0); //FIXME RtlFreeHeap (SmpHeap, 0, Client); -- SmpClientDirectory.Count; } @@ -285,7 +391,7 @@ SmGetClientBasicInformation (PSM_BASIC_INFORMATION i) { INT Index = 0; - PSM_CLIENT_DATA Client = NULL; + PSM_CLIENT_DATA ClientData = NULL;
DPRINT("SM: %s called\n", __FUNCTION__);
@@ -296,13 +402,13 @@ if (SmpClientDirectory.Count > 0) { - Client = SmpClientDirectory.Client; - while ((NULL != Client) && (Index < SM_QRYINFO_MAX_SS_COUNT)) + ClientData = SmpClientDirectory.Client; + while ((NULL != ClientData) && (Index < SM_QRYINFO_MAX_SS_COUNT)) { - i->SubSystem[Index].Id = Client->SubsystemId; - i->SubSystem[Index].Flags = 0; /* TODO */ - i->SubSystem[Index].ProcessId = 0; /* TODO */ - Client = Client->Next; + i->SubSystem[Index].Id = ClientData->SubsystemId; + i->SubSystem[Index].Flags = ClientData->Flags; + i->SubSystem[Index].ProcessId = ClientData->ServerProcessId; + ClientData = ClientData->Next; } }
@@ -316,9 +422,27 @@ NTSTATUS FASTCALL SmGetSubSystemInformation (PSM_SUBSYSTEM_INFORMATION i) { + NTSTATUS Status = STATUS_SUCCESS; + PSM_CLIENT_DATA ClientData = NULL; + DPRINT("SM: %s called\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED; + RtlEnterCriticalSection (& SmpClientDirectory.Lock); + ClientData = SmpLookupClient (i->SubSystemId, NULL); + if (NULL == ClientData) + { + Status = STATUS_NOT_FOUND; + } + else + { + i->Flags = ClientData->Flags; + i->ProcessId = ClientData->ServerProcessId; + RtlCopyMemory (i->NameSpaceRootNode, + ClientData->SbApiPortName, + (SM_QRYINFO_MAX_ROOT_NODE * sizeof(i->NameSpaceRootNode[0]))); + } + RtlLeaveCriticalSection (& SmpClientDirectory.Lock); + return Status; }
/* EOF */ _____
Modified: trunk/reactos/subsys/smss/initmv.c --- trunk/reactos/subsys/smss/initmv.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/initmv.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -23,6 +23,7 @@
* * -------------------------------------------------------------------- */ +
#include "smss.h"
@@ -35,6 +36,13 @@ DPRINT("SmProcessFileRenameList() called\n");
/* FIXME: implement it! */ +/* + * open HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\FileRenameOperations + * for each item in its value + * clone the old file in the new name, + * delete the source. + * + */
DPRINT("SmProcessFileRenameList() done\n");
_____
Modified: trunk/reactos/subsys/smss/initrun.c --- trunk/reactos/subsys/smss/initrun.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/initrun.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -29,7 +29,7 @@
#define NDEBUG #include <debug.h>
-HANDLE Children[2] = {0, 0}; /* csrss, winlogon */ +//HANDLE Children[2] = {0, 0}; /* csrss, winlogon */
/********************************************************************** @@ -99,10 +99,12 @@ Status = SmCreateUserProcess (ImagePath, CommandLine, TRUE, /* wait */ - NULL, - TRUE, /* terminate */ - NULL); - + NULL, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: %s: running '$S' failed (Status=0x%08lx)\n", + __FUNCTION__, Status); + } return(STATUS_SUCCESS); }
_____
Modified: trunk/reactos/subsys/smss/initss.c --- trunk/reactos/subsys/smss/initss.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/initss.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -55,23 +55,40 @@
SmpRegisterSmss(VOID) { NTSTATUS Status = STATUS_SUCCESS; - UNICODE_STRING SbApiPortName = {0,0,NULL}; + RTL_PROCESS_INFO ProcessInfo;
DPRINT("SM: %s called\n",__FUNCTION__); - - RtlInitUnicodeString (& SbApiPortName, L""); - Status = SmConnectApiPort(& SbApiPortName, - (HANDLE) -1, /* SM has no SB port */ - IMAGE_SUBSYSTEM_NATIVE, - & hSmApiPort); - if(!NT_SUCCESS(Status)) + + RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo); + ProcessInfo.Size = sizeof ProcessInfo; + ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId; + ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId; + DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n", + __FUNCTION__,ProcessInfo.ProcessHandle); + Status = SmCreateClient (& ProcessInfo, L"Session Manager"); + if (NT_SUCCESS(Status)) { - DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n", - __FUNCTION__,Status); - return Status; + UNICODE_STRING SbApiPortName = {0,0,NULL}; + + RtlInitUnicodeString (& SbApiPortName, L""); + Status = SmConnectApiPort(& SbApiPortName, + (HANDLE) -1, /* SM has no SB port */ + IMAGE_SUBSYSTEM_NATIVE, + & hSmApiPort); + if(!NT_SUCCESS(Status)) + { + DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n", + __FUNCTION__,Status); + return Status; + } + DPRINT("SM self registered\n"); } - DPRINT("SM self registered\n"); + else + { + DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n", + __FUNCTION__, Status); + } /* * Note that you don't need to call complete session * because connection handling code autocompletes _____
Modified: trunk/reactos/subsys/smss/smapi.c --- trunk/reactos/subsys/smss/smapi.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/smapi.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -52,12 +52,13 @@
#endif
/********************************************************************** - * SmpCallback/2 + * SmpCallbackServer/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. + * DESCRIPTION + * The SM calls back a previously connected subsystem process to + * authorize 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, @@ -72,7 +73,8 @@
DPRINT("SM: %s called\n", __FUNCTION__);
- if(IMAGE_SUBSYSTEM_NATIVE == ConnectData->SubSystemId) + if ( (IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->SubSystemId) || + (IMAGE_SUBSYSTEM_NATIVE == ConnectData->SubSystemId)) { DPRINT("SM: %s: we do not need calling back SM!\n", __FUNCTION__); @@ -210,12 +212,10 @@ { DPRINT("SM: %s: id = %d\n", __FUNCTION__, ConnectData->SubSystemId); /* - * 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) + * SmBeginClientInitialization/2 will succeed only if there + * is a candidate client ready. */ - Status = SmCreateClient (Request, & ClientData); + Status = SmBeginClientInitialization (Request, & ClientData); if(STATUS_SUCCESS == Status) { DPRINT("SM: %s: ClientData = 0x%08lx\n", @@ -310,7 +310,7 @@ * * DECRIPTION * Due to differences in LPC implementation between NT and ROS, - * we need a thread to listen for connection request that + * we need a thread to listen to for connection request that * creates a new thread for each connected port. This is not * necessary in NT LPC, because server side connected ports are * never used to receive requests. _____
Modified: trunk/reactos/subsys/smss/smapicomp.c --- trunk/reactos/subsys/smss/smapicomp.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/smapicomp.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -34,16 +34,20 @@
*/ SMAPI(SmCompSes) { - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status = STATUS_SUCCESS;
DPRINT("SM: %s called\n", __FUNCTION__); - - Status = SmCompleteClientInitialization (Request->Header.ClientId.UniqueProcess); - if(!NT_SUCCESS(Status)) + + DPRINT("SM: %s: ClientId.UniqueProcess=%lx\n", + __FUNCTION__, Request->Header.ClientId.UniqueProcess); + Status = SmCompleteClientInitialization ((ULONG) Request->Header.ClientId.UniqueProcess); + if (!NT_SUCCESS(Status)) { - Request->SmHeader.Status = STATUS_UNSUCCESSFUL; + DPRINT1("SM: %s: NtQueryInformationProcess failed (Status=0x%08lx)\n", + __FUNCTION__, Status); } - return Status; + Request->SmHeader.Status = Status; + return STATUS_SUCCESS; }
_____
Modified: trunk/reactos/subsys/smss/smapiexec.c --- trunk/reactos/subsys/smss/smapiexec.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/smapiexec.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -31,15 +31,27 @@
/********************************************************************** * SmCreateUserProcess/5 * + * DESCRIPTION + * + * ARGUMENTS + * ImagePath: bsolute path of the image to run; + * CommandLine: arguments and options for ImagePath; + * WaitForIt: TRUE for boot time processes and FALSE for + * subsystems bootstrapping; + * Timeout: optional: used if WaitForIt==TRUE; + * ProcessHandle: optional: a duplicated handle for + the child process (storage provided by the caller). + * + * RETURN VALUE + * NTSTATUS: + * */ NTSTATUS STDCALL SmCreateUserProcess (LPWSTR ImagePath, LPWSTR CommandLine, BOOLEAN WaitForIt, PLARGE_INTEGER Timeout OPTIONAL, - BOOLEAN TerminateIt, - PRTL_PROCESS_INFO UserProcessInfo OPTIONAL - ) + PRTL_PROCESS_INFO UserProcessInfo OPTIONAL) { UNICODE_STRING ImagePathString = {0}; UNICODE_STRING CommandLineString = {0}; @@ -48,9 +60,13 @@ PRTL_PROCESS_INFO pProcessInfo = & ProcessInfo; NTSTATUS Status = STATUS_SUCCESS;
+ DPRINT("SM: %s called\n", __FUNCTION__); + + if (NULL != UserProcessInfo) + { + pProcessInfo = UserProcessInfo; + }
- DPRINT("SM: %s called\n",__FUNCTION__); - RtlInitUnicodeString (& ImagePathString, ImagePath); RtlInitUnicodeString (& CommandLineString, CommandLine);
@@ -65,12 +81,6 @@ NULL, NULL);
- if(NULL != UserProcessInfo) - { - /* Use caller provided storage */ - pProcessInfo = UserProcessInfo; - } - Status = RtlCreateUserProcess (& ImagePathString, OBJ_CASE_INSENSITIVE, ProcessParameters, @@ -82,7 +92,7 @@ NULL, pProcessInfo);
- RtlDestroyProcessParameters (ProcessParameters); + RtlDestroyProcessParameters (ProcessParameters);
if (!NT_SUCCESS(Status)) { @@ -90,25 +100,52 @@ __FUNCTION__, ImagePathString.Buffer, Status); return Status; } - - ZwResumeThread(pProcessInfo->ThreadHandle, NULL); - - - /* Wait for process termination */ - if(WaitForIt) + /* + * It the caller is *not* interested in the child info, + * resume it immediately. + */ + if (NULL == UserProcessInfo) { - NtWaitForSingleObject (pProcessInfo->ProcessHandle, - FALSE, - Timeout); + Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL); + if(!NT_SUCCESS(Status)) + { + DPRINT1("SM: %s: NtResumeThread failed (Status=0x%08lx)\n", + __FUNCTION__, Status); + } } + else + { + HANDLE DupProcessHandle = (HANDLE) 0; + + Status = NtDuplicateObject (NtCurrentProcess(), + pProcessInfo->ProcessHandle, + NtCurrentProcess(), + & DupProcessHandle, + PROCESS_ALL_ACCESS, + 0, 0); + if(!NT_SUCCESS(Status)) + { + DPRINT1("SM: %s: NtDuplicateObject failed (Status=0x%08lx)\n", + __FUNCTION__, Status); + } + pProcessInfo->ProcessHandle = DupProcessHandle; + + }
- /* Terminate process */ - if(TerminateIt) + /* Wait for process termination */ + if (WaitForIt) { - NtClose(pProcessInfo->ThreadHandle); - NtClose(pProcessInfo->ProcessHandle); + Status = NtWaitForSingleObject (pProcessInfo->ProcessHandle, + FALSE, + Timeout); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SM: %s: NtWaitForSingleObject failed with Status=0x%08lx\n", + __FUNCTION__, Status); + } + } - return STATUS_SUCCESS; + return Status; }
/********************************************************************** @@ -259,61 +296,94 @@ (ExecPgm->NameLength <= SM_EXEXPGM_MAX_LENGTH) && TRUE /* TODO: check LPC payload size */) { + WCHAR Data [MAX_PATH + 1] = {0}; + ULONG DataLength = sizeof Data; + ULONG DataType = REG_EXPAND_SZ; + RtlZeroMemory (Name, sizeof Name); RtlCopyMemory (Name, ExecPgm->Name, (sizeof ExecPgm->Name[0] * ExecPgm->NameLength)); DPRINT("SM: %s: Name='%S'\n", __FUNCTION__, Name); - /* - * Check if program name is internal - * (Is this correct? Debug is in the registry too) - */ - if(0 == _wcsicmp(L"DEBUG", Name)) + /* Lookup Name in the registry */ + Status = SmLookupSubsystem (Name, + Data, + & DataLength, + & DataType, + TRUE); /* expand */ + if(NT_SUCCESS(Status)) { - /* - * Initialize DBGSS. - * NOTE: probably in early prototypes it was an - * independent process; now it is embedded in the - * SM for performance or security. - */ - Request->SmHeader.Status = SmInitializeDbgSs(); - } - else - { - WCHAR Data [MAX_PATH + 1] = {0}; - ULONG DataLength = sizeof Data; - ULONG DataType = REG_EXPAND_SZ; - - /* Lookup Name in the registry */ - Status = SmLookupSubsystem (Name, - Data, - & DataLength, - & DataType, - TRUE); /* expand */ - if(NT_SUCCESS(Status)) + /* Is the subsystem definition non-empty? */ + if (DataLength > sizeof Data[0]) { WCHAR ImagePath [MAX_PATH + 1] = {0}; + PWCHAR CommandLine = ImagePath; + RTL_PROCESS_INFO ProcessInfo = {0};
wcscpy (ImagePath, L"\??\"); wcscat (ImagePath, Data); - - /* Create native process */ - Request->SmHeader.Status = SmCreateUserProcess(ImagePath, - L"", /* FIXME */ - FALSE, /* wait */ - NULL, - FALSE, /* terminate */ - NULL); - }else{ - Request->SmHeader.Status = Status; + /* + * Look for the beginning of the command line. + */ + for (; (*CommandLine != L'\0') && (*CommandLine != L' '); + CommandLine ++); + for (; *CommandLine == L' '; CommandLine ++) + { + *CommandLine = L'\0'; + } + /* + * Create a native process (suspended). + */ + ProcessInfo.Size = sizeof ProcessInfo; + Request->SmHeader.Status = + SmCreateUserProcess(ImagePath, + CommandLine, + FALSE, /* wait */ + NULL, /* timeout */ + & ProcessInfo); + if (NT_SUCCESS(Request->SmHeader.Status)) + { + Status = SmCreateClient (& ProcessInfo, Name); + if (NT_SUCCESS(Status)) + { + Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL); + if (!NT_SUCCESS(Status)) + { + //Status = SmDestroyClient TODO + } + } else { + DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n", + __FUNCTION__, Status); + } + } } + else + { + /* + * OK, the definition is empty, but check + * if it is the name of an embedded subsystem. + */ + if(0 == _wcsicmp(L"DEBUG", Name)) + { + /* + * Initialize the embedded DBGSS. + */ + Request->SmHeader.Status = SmInitializeDbgSs(); + } + else + { + /* + * Badly defined subsystem. Check the registry! + */ + Request->SmHeader.Status = STATUS_NOT_FOUND; + } + } + } else { + /* It couldn't lookup the Name! */ + Request->SmHeader.Status = Status; } } - else - { - Request->SmHeader.Status = Status = STATUS_INVALID_PARAMETER; - } return Status; }
_____
Modified: trunk/reactos/subsys/smss/smss.c --- trunk/reactos/subsys/smss/smss.c 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/smss.c 2005-05-22 15:54:15 UTC (rev 15467) @@ -30,16 +30,18 @@
#define NDEBUG #include <debug.h>
-HANDLE SmSsProcessId = 0; +ULONG SmSsProcessId = 0;
/* Native image's entry point */
VOID STDCALL NtProcessStartup(PPEB Peb) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PROCESS_BASIC_INFORMATION PBI = {0};
+PrintString("*** EXPERIMENTAL ***\n"); + PrintString("ReactOS Session Manager %s (Build %s)\n", KERNEL_RELEASE_STR, KERNEL_VERSION_BUILD_STR); @@ -52,7 +54,7 @@ NULL); if(NT_SUCCESS(Status)) { - SmSsProcessId = PBI.UniqueProcessId; + SmSsProcessId = (ULONG) PBI.UniqueProcessId; } /* Initialize the system */ Status = InitSessionManager(); _____
Modified: trunk/reactos/subsys/smss/smss.h --- trunk/reactos/subsys/smss/smss.h 2005-05-22 12:29:10 UTC (rev 15466) +++ trunk/reactos/subsys/smss/smss.h 2005-05-22 15:54:15 UTC (rev 15467) @@ -6,11 +6,8 @@
#include <sm/api.h> #include <sm/helper.h>
-#define CHILD_CSRSS 0 -#define CHILD_WINLOGON 1 - /* smss.c */ -extern HANDLE SmSsProcessId; +extern ULONG SmSsProcessId;
/* init.c */ NTSTATUS InitSessionManager(VOID); @@ -63,8 +60,7 @@ LPWSTR CommandLine, BOOLEAN WaitForIt, PLARGE_INTEGER Timeout OPTIONAL, - BOOLEAN TerminateIt, - PRTL_PROCESS_INFO ProcessInfo OPTIONAL); + PRTL_PROCESS_INFO UserProcessInfo OPTIONAL); NTSTATUS STDCALL SmLookupSubsystem (IN PWSTR Name, IN OUT PWSTR Data, @@ -80,22 +76,30 @@ NTSTATUS FASTCALL SmQryInfo(PSM_PORT_MESSAGE);
/* client.c */ +#define SM_CLIENT_FLAG_CANDIDATE 0x8000 +#define SM_CLIENT_FLAG_INITIALIZED 0x0001 +#define SM_CLIENT_FLAG_REQUIRED 0x0002 typedef struct _SM_CLIENT_DATA { - USHORT SubsystemId; - BOOL Initialized; - HANDLE ServerProcess; - HANDLE ApiPort; - HANDLE ApiPortThread; - HANDLE SbApiPort; - WCHAR SbApiPortName [SM_SB_NAME_MAX_LENGTH]; - struct _SM_CLIENT_DATA * Next; + RTL_CRITICAL_SECTION Lock; + WCHAR ProgramName [SM_SB_NAME_MAX_LENGTH]; + USHORT SubsystemId; + WORD Flags; [truncated at 1000 lines; 22 more skipped]