ReactOS 0.4.16-dev-136-g52192f1
smsubsys.c File Reference
#include "smss.h"
#include <debug.h>
Include dependency graph for smsubsys.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI SmpCallCsrCreateProcess (IN PSB_API_MSG SbApiMsg, IN USHORT MessageLength, IN HANDLE PortHandle)
 
VOID NTAPI SmpDereferenceSubsystem (IN PSMP_SUBSYSTEM SubSystem)
 
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByCid (IN PCLIENT_ID ClientId)
 
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType (IN ULONG MuSessionId, IN ULONG ImageType)
 
NTSTATUS NTAPI SmpLoadSubSystem (IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
 
NTSTATUS NTAPI SmpLoadSubSystemsForMuSession (IN PULONG MuSessionId, OUT PHANDLE ProcessId, IN PUNICODE_STRING InitialCommand)
 

Variables

RTL_CRITICAL_SECTION SmpKnownSubSysLock
 
LIST_ENTRY SmpKnownSubSysHead
 
HANDLE SmpWindowsSubSysProcess
 
HANDLE SmpWindowsSubSysProcessId
 
BOOLEAN RegPosixSingleInstance
 
WCHAR InitialCommandBuffer [256]
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file smsubsys.c.

Function Documentation

◆ SmpCallCsrCreateProcess()

NTSTATUS NTAPI SmpCallCsrCreateProcess ( IN PSB_API_MSG  SbApiMsg,
IN USHORT  MessageLength,
IN HANDLE  PortHandle 
)

Definition at line 29 of file smsubsys.c.

32{
34
35 /* Initialize the header and send the message to CSRSS */
36 SbApiMsg->h.u2.ZeroInit = 0;
37 SbApiMsg->h.u1.s1.DataLength = MessageLength + 8;
38 SbApiMsg->h.u1.s1.TotalLength = sizeof(SB_API_MSG);
39 SbApiMsg->ApiNumber = SbpCreateProcess;
40 Status = NtRequestWaitReplyPort(PortHandle, &SbApiMsg->h, &SbApiMsg->h);
41 if (NT_SUCCESS(Status)) Status = SbApiMsg->ReturnValue;
42 return Status;
43}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI NtRequestWaitReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply)
Definition: send.c:696
@ SbpCreateProcess
Definition: smmsg.h:149
struct _SB_API_MSG SB_API_MSG

Referenced by SmpLoadSubSystem().

◆ SmpDereferenceSubsystem()

VOID NTAPI SmpDereferenceSubsystem ( IN PSMP_SUBSYSTEM  SubSystem)

Definition at line 47 of file smsubsys.c.

48{
49 /* Acquire the database lock while we (potentially) destroy this subsystem */
51
52 /* Drop the reference and see if it's terminating */
53 if (!(--SubSystem->ReferenceCount) && (SubSystem->Terminating))
54 {
55 /* Close all handles and free it */
56 if (SubSystem->Event) NtClose(SubSystem->Event);
57 if (SubSystem->ProcessHandle) NtClose(SubSystem->ProcessHandle);
58 if (SubSystem->SbApiPort) NtClose(SubSystem->SbApiPort);
59 RtlFreeHeap(SmpHeap, 0, SubSystem);
60 }
61
62 /* Release the database lock */
64}
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
PVOID SmpHeap
Definition: sminit.c:25
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18

Referenced by SmpHandleConnectionRequest(), SmpLoadSubSystem(), and SmpSbCreateSession().

◆ SmpLoadSubSystem()

NTSTATUS NTAPI SmpLoadSubSystem ( IN PUNICODE_STRING  FileName,
IN PUNICODE_STRING  Directory,
IN PUNICODE_STRING  CommandLine,
IN ULONG  MuSessionId,
OUT PHANDLE  ProcessId,
IN ULONG  Flags 
)

Definition at line 138 of file smsubsys.c.

144{
145 PSMP_SUBSYSTEM Subsystem, NewSubsystem, KnownSubsystem = NULL;
146 HANDLE SubSysProcessId;
148 SB_API_MSG SbApiMsg;
149 RTL_USER_PROCESS_INFORMATION ProcessInformation;
151 PVOID State;
154
155 /* Make sure this is a found subsystem */
157 {
158 DPRINT1("SMSS: Unable to find subsystem - %wZ\n", FileName);
160 }
161
162 /* Don't use a session if the flag is set */
163 if (Flags & 0x80) MuSessionId = 0;
164
165 /* Lock the subsystems while we do a look up */
167 while (TRUE)
168 {
169 /* Check if we found a subsystem not yet fully initialized */
170 Subsystem = SmpLocateKnownSubSysByType(MuSessionId, -1);
171 if (!Subsystem) break;
173
174 /* Wait on it to initialize */
176
177 /* Dereference it and try the next one */
179 SmpDereferenceSubsystem(Subsystem);
180 }
181
182 /* Check if this is a POSIX subsystem */
183 if (Flags & SMP_POSIX_FLAG)
184 {
185 /* Do we already have it? */
187 }
188 else if (Flags & SMP_OS2_FLAG)
189 {
190 /* This is an OS/2 subsystem, do we we already have it? */
191 Subsystem = SmpLocateKnownSubSysByType(MuSessionId, IMAGE_SUBSYSTEM_OS2_CUI);
192 }
193
194 /* Check if we already have one of the optional subsystems for the session */
195 if (Subsystem)
196 {
197 /* Dereference and return, no work to do */
198 SmpDereferenceSubsystem(Subsystem);
200 return STATUS_SUCCESS;
201 }
202
203 /* Allocate a new subsystem! */
204 NewSubsystem = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_SUBSYSTEM));
205 if (!NewSubsystem)
206 {
208 return STATUS_NO_MEMORY;
209 }
210
211 /* Initialize its header and reference count */
212 NewSubsystem->ReferenceCount = 1;
213 NewSubsystem->MuSessionId = MuSessionId;
214 NewSubsystem->ImageType = -1;
215
216 /* Clear out all the other data for now */
217 NewSubsystem->Terminating = FALSE;
218 NewSubsystem->ProcessHandle = NULL;
219 NewSubsystem->Event = NULL;
220 NewSubsystem->PortHandle = NULL;
221 NewSubsystem->SbApiPort = NULL;
222
223 /* Create the event we'll be waiting on for initialization */
224 Status = NtCreateEvent(&NewSubsystem->Event,
226 NULL,
228 FALSE);
229 if (!NT_SUCCESS(Status))
230 {
231 /* This failed, bail out */
232 RtlFreeHeap(SmpHeap, 0, NewSubsystem);
234 return STATUS_NO_MEMORY;
235 }
236
237 /* Insert the subsystem and release the lock. It can now be found */
238 InsertTailList(&SmpKnownSubSysHead, &NewSubsystem->Entry);
240
241 /* The OS/2 and POSIX subsystems are actually Windows applications! */
243 {
244 /* Locate the Windows subsystem for this session */
245 KnownSubsystem = SmpLocateKnownSubSysByType(MuSessionId,
247 if (!KnownSubsystem)
248 {
249 DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed\n");
250 goto Quickie2;
251 }
252
253 /* Fill out all the process details and call CSRSS to launch it */
254 CreateProcess->In.ImageName = FileName;
255 CreateProcess->In.CurrentDirectory = Directory;
256 CreateProcess->In.CommandLine = CommandLine;
260 CreateProcess->In.DebugFlags = SmpDebug;
262 sizeof(*CreateProcess),
263 KnownSubsystem->SbApiPort);
264 if (!NT_SUCCESS(Status))
265 {
266 /* Handle failures */
267 DPRINT1("SMSS: SmpLoadSubSystem - SmpCallCsrCreateProcess Failed with Status %lx\n",
268 Status);
269 goto Quickie2;
270 }
271
272 /* Save the process information we'll need for the create session */
273 ProcessInformation.ProcessHandle = CreateProcess->Out.ProcessHandle;
274 ProcessInformation.ThreadHandle = CreateProcess->Out.ThreadHandle;
275 ProcessInformation.ClientId = CreateProcess->Out.ClientId;
276 ProcessInformation.ImageInformation.SubSystemType = CreateProcess->Out.SubsystemType;
277 }
278 else
279 {
280 /* This must be CSRSS itself, so just launch it and that's it */
282 Directory,
283 CommandLine,
284 MuSessionId,
286 &ProcessInformation);
287 if (!NT_SUCCESS(Status))
288 {
289 /* Handle failures */
290 DPRINT1("SMSS: SmpLoadSubSystem - SmpExecuteImage Failed with Status %lx\n",
291 Status);
292 goto Quickie2;
293 }
294 }
295
296 /* Fill out the handle and client ID in the subsystem structure now */
297 NewSubsystem->ProcessHandle = ProcessInformation.ProcessHandle;
298 NewSubsystem->ClientId = ProcessInformation.ClientId;
299
300 /* Check if we launched a native image or a subsystem-backed image */
301 if (ProcessInformation.ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE)
302 {
303 /* This must be CSRSS itself, since it's a native subsystem image */
304 SubSysProcessId = ProcessInformation.ClientId.UniqueProcess;
305 if ((ProcessId) && !(*ProcessId)) *ProcessId = SubSysProcessId;
306
307 /* Was this the initial CSRSS on Session 0? */
308 if (!MuSessionId)
309 {
310 /* Then save it in the global variables */
311 SmpWindowsSubSysProcessId = SubSysProcessId;
312 SmpWindowsSubSysProcess = ProcessInformation.ProcessHandle;
313 }
315 }
316 else
317 {
318 /* This is the POSIX or OS/2 subsystem process, copy its information */
319 CreateSession->ProcessInfo = ProcessInformation;
320
321 CreateSession->DbgSessionId = 0;
322 *(PULONGLONG)&CreateSession->DbgUiClientId = 0;
323
324 /* This should find CSRSS because they are POSIX or OS/2 subsystems */
325 Subsystem = SmpLocateKnownSubSysByType(MuSessionId,
326 ProcessInformation.ImageInformation.SubSystemType);
327 if (!Subsystem)
328 {
329 /* Odd failure -- but handle it anyway */
331 DPRINT1("SMSS: SmpLoadSubSystem - SmpLocateKnownSubSysByType Failed with Status %lx for sessionid %lu\n",
332 Status,
333 MuSessionId);
334 goto Quickie;
335 }
336
337 /* Duplicate the parent process handle for the subsystem to have */
339 ProcessInformation.ProcessHandle,
340 Subsystem->ProcessHandle,
341 &CreateSession->ProcessInfo.ProcessHandle,
343 0,
344 0);
345 if (!NT_SUCCESS(Status))
346 {
347 /* Fail since this is critical */
348 DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %lu\n",
349 Status,
350 MuSessionId);
351 goto Quickie;
352 }
353
354 /* Duplicate the initial thread handle for the subsystem to have */
356 ProcessInformation.ThreadHandle,
357 Subsystem->ProcessHandle,
358 &CreateSession->ProcessInfo.ThreadHandle,
360 0,
361 0);
362 if (!NT_SUCCESS(Status))
363 {
364 /* Fail since this is critical */
365 DPRINT1("SMSS: SmpLoadSubSystem - NtDuplicateObject Failed with Status %lx for sessionid %lu\n",
366 Status,
367 MuSessionId);
368 goto Quickie;
369 }
370
371 /* Allocate an internal Session ID for this subsystem */
372 CreateSession->SessionId = SmpAllocateSessionId(Subsystem, NULL);
373
374 /* Send the create session message to the subsystem */
375 SbApiMsg.ReturnValue = STATUS_SUCCESS;
376 SbApiMsg.h.u2.ZeroInit = 0;
377 SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
378 SbApiMsg.h.u1.s1.TotalLength = sizeof(SB_API_MSG);
379 SbApiMsg.ApiNumber = SbpCreateSession;
381 &SbApiMsg.h,
382 &SbApiMsg.h);
383 if (NT_SUCCESS(Status)) Status = SbApiMsg.ReturnValue;
384 if (!NT_SUCCESS(Status))
385 {
386 /* Delete the session and handle failure if the LPC call failed */
388 DPRINT1("SMSS: SmpLoadSubSystem - NtRequestWaitReplyPort Failed with Status %lx for sessionid %lu\n",
389 Status,
390 MuSessionId);
391 goto Quickie;
392 }
393 }
394
395 /* Okay, everything looks good to go, initialize this subsystem now! */
396 Status = NtResumeThread(ProcessInformation.ThreadHandle, NULL);
397 if (!NT_SUCCESS(Status))
398 {
399 /* That didn't work -- back out of everything */
400 DPRINT1("SMSS: SmpLoadSubSystem - NtResumeThread failed Status %lx\n", Status);
401 goto Quickie;
402 }
403
404 /* Check if this was the subsystem for a different session */
405 if (MuSessionId)
406 {
407 /* Wait up to 60 seconds for it to initialize */
408 Timeout.QuadPart = -600000000;
409 Status = NtWaitForSingleObject(NewSubsystem->Event, FALSE, &Timeout);
410
411 /* Timeout is done -- does this session still exist? */
412 if (!SmpCheckDuplicateMuSessionId(MuSessionId))
413 {
414 /* Nope, it died. Cleanup should've ocurred in a different path. */
415 DPRINT1("SMSS: SmpLoadSubSystem - session deleted\n");
417 }
418
419 /* Check if we timed our or there was another error with the wait */
420 if (Status != STATUS_WAIT_0)
421 {
422 /* Something is wrong with the subsystem, so back out of everything */
423 DPRINT1("SMSS: SmpLoadSubSystem - Timeout waiting for subsystem connect with Status %lx for sessionid %lu\n",
424 Status,
425 MuSessionId);
426 goto Quickie;
427 }
428 }
429 else
430 {
431 /* This a session 0 subsystem, just wait for it to initialize */
432 NtWaitForSingleObject(NewSubsystem->Event, FALSE, NULL);
433 }
434
435 /* Subsystem is created, resumed, and initialized. Close handles and exit */
436 NtClose(ProcessInformation.ThreadHandle);
438 goto Quickie2;
439
440Quickie:
441 /* This is the failure path. First check if we need to detach from session */
442 if ((AttachedSessionId == -1) || (Flags & (SMP_POSIX_FLAG | SMP_OS2_FLAG)))
443 {
444 /* We were not attached, or did not launch subsystems that required it */
445 DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n",
448 Status);
449 }
450 else
451 {
452 /* Get the privilege we need for detachment */
454 if (!NT_SUCCESS(Status))
455 {
456 /* We can't detach without it */
457 DPRINT1("SMSS: Did not detach from Session Space: SessionId=%x Flags=%x Status=%x\n",
460 Status);
461 }
462 else
463 {
464 /* Now detach from the session */
467 sizeof(AttachedSessionId));
468 if (!NT_SUCCESS(Status))
469 {
470 /* Failed to detach. Note the DPRINT1 has a typo in Windows */
471 DPRINT1("SMSS: SmpStartCsr, Couldn't Detach from Session Space. Status=%x\n", Status);
473 }
474 else
475 {
476 /* Detachment worked, reset our attached session ID */
478 }
479
480 /* And release the privilege we acquired */
482 }
483 }
484
485 /* Since this is the failure path, terminate the subsystem process */
486 NtTerminateProcess(ProcessInformation.ProcessHandle, Status);
487 NtClose(ProcessInformation.ThreadHandle);
488
489Quickie2:
490 /* This is the cleanup path -- first dereference our subsystems */
492 if (Subsystem) SmpDereferenceSubsystem(Subsystem);
493 if (KnownSubsystem) SmpDereferenceSubsystem(KnownSubsystem);
494
495 /* In the failure case, destroy the new subsystem we just created */
496 if (!NT_SUCCESS(Status))
497 {
498 RemoveEntryList(&NewSubsystem->Entry);
499 NtSetEvent(NewSubsystem->Event, NULL);
500 SmpDereferenceSubsystem(NewSubsystem);
501 }
502
503 /* Finally, we're all done! */
505 return Status;
506}
NTSYSAPI NTSTATUS NTAPI NtSetSystemInformation(IN INT SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength)
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
struct _FileName FileName
Definition: fatprocs.h:897
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
MMRESULT CreateSession(DeviceType device_type, UINT device_id, SessionInfo **session_info)
Definition: session.c:63
#define ASSERT(a)
Definition: mode.c:44
#define SE_LOAD_DRIVER_PRIVILEGE
Definition: security.c:664
@ SystemSessionDetach
Definition: extypes.h:265
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
@ NotificationEvent
#define IMAGE_SUBSYSTEM_POSIX_CUI
Definition: ntimage.h:440
#define IMAGE_SUBSYSTEM_OS2_CUI
Definition: ntimage.h:439
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define IMAGE_SUBSYSTEM_NATIVE
Definition: ntimage.h:436
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NO_SUCH_PACKAGE
Definition: ntstatus.h:490
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
static ULONG Timeout
Definition: ping.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG SmBaseTag
Definition: sminit.c:26
UNICODE_STRING SmpDefaultLibPath
Definition: sminit.c:29
struct _SB_CREATE_SESSION_MSG SB_CREATE_SESSION_MSG
@ SbpCreateSession
Definition: smmsg.h:146
BOOLEAN NTAPI SmpCheckDuplicateMuSessionId(IN ULONG MuSessionId)
Definition: smsessn.c:37
ULONG NTAPI SmpAllocateSessionId(IN PSMP_SUBSYSTEM Subsystem, IN PSMP_SUBSYSTEM OtherSubsystem)
Definition: smsessn.c:123
VOID NTAPI SmpDeleteSession(IN ULONG SessionId)
Definition: smsessn.c:98
BOOLEAN SmpDebug
Definition: smss.c:22
ULONG AttachedSessionId
Definition: smss.c:21
NTSTATUS NTAPI SmpExecuteImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING Directory, IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, IN ULONG Flags, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation)
Definition: smss.c:30
#define SMP_OS2_FLAG
Definition: smss.h:51
VOID NTAPI SmpReleasePrivilege(IN PVOID State)
Definition: smutil.c:129
#define SMP_DEFERRED_FLAG
Definition: smss.h:49
#define SMP_POSIX_FLAG
Definition: smss.h:50
NTSTATUS NTAPI SmpAcquirePrivilege(IN ULONG Privilege, OUT PVOID *PrivilegeStat)
Definition: smutil.c:40
#define SMP_INVALID_PATH
Definition: smss.h:48
HANDLE SmpWindowsSubSysProcess
Definition: smsubsys.c:20
NTSTATUS NTAPI SmpCallCsrCreateProcess(IN PSB_API_MSG SbApiMsg, IN USHORT MessageLength, IN HANDLE PortHandle)
Definition: smsubsys.c:29
VOID NTAPI SmpDereferenceSubsystem(IN PSMP_SUBSYSTEM SubSystem)
Definition: smsubsys.c:47
PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType(IN ULONG MuSessionId, IN ULONG ImageType)
Definition: smsubsys.c:102
HANDLE SmpWindowsSubSysProcessId
Definition: smsubsys.c:21
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
base for all directory entries
Definition: entries.h:138
HANDLE UniqueProcess
Definition: compat.h:825
SECTION_IMAGE_INFORMATION ImageInformation
Definition: rtltypes.h:1573
NTSTATUS ReturnValue
Definition: smmsg.h:239
SB_API_NUMBER ApiNumber
Definition: smmsg.h:238
union _SB_API_MSG::@3526::@3528::@3530 u
SB_CREATE_PROCESS_MSG CreateProcess
Definition: smmsg.h:245
SB_CREATE_SESSION_MSG CreateSession
Definition: smmsg.h:242
PORT_MESSAGE h
Definition: smmsg.h:232
ULONG MuSessionId
Definition: smss.h:72
HANDLE ProcessHandle
Definition: smss.h:67
HANDLE SbApiPort
Definition: smss.h:70
CLIENT_ID ClientId
Definition: smss.h:71
HANDLE Event
Definition: smss.h:66
ULONG ImageType
Definition: smss.h:68
BOOLEAN Terminating
Definition: smss.h:73
LIST_ENTRY Entry
Definition: smss.h:65
HANDLE PortHandle
Definition: smss.h:69
ULONG ReferenceCount
Definition: smss.h:74
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define CreateProcess
Definition: winbase.h:3758
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by SmpExecuteCommand().

◆ SmpLoadSubSystemsForMuSession()

NTSTATUS NTAPI SmpLoadSubSystemsForMuSession ( IN PULONG  MuSessionId,
OUT PHANDLE  ProcessId,
IN PUNICODE_STRING  InitialCommand 
)

Definition at line 510 of file smsubsys.c.

513{
514 NTSTATUS Status = STATUS_SUCCESS, Status2;
517 PLIST_ENTRY NextEntry;
519 PVOID State;
520
521 /* Write a few last registry keys with the boot partition information */
523
524 /* Process "SetupExecute" values */
525 NextEntry = SmpSetupExecuteList.Flink;
526 while (NextEntry != &SmpSetupExecuteList)
527 {
528 /* Execute each one and move on */
530 SmpExecuteCommand(&RegEntry->Name, 0, NULL, 0);
531 NextEntry = NextEntry->Flink;
532 }
533
534 /* Now process the subsystems */
535 NextEntry = SmpSubSystemList.Flink;
536 while (NextEntry != &SmpSubSystemList)
537 {
538 /* Get the entry and check if this is the special Win32k entry */
540 if (_wcsicmp(RegEntry->Name.Buffer, L"Kmode") == 0)
541 {
542 /* Translate it */
543 if (!RtlDosPathNameToNtPathName_U(RegEntry->Value.Buffer,
544 &NtPath,
545 NULL,
546 NULL))
547 {
549 DPRINT1("Failed: %lx\n", Status);
550 }
551 else
552 {
553 /* Get the driver privilege */
555 if (NT_SUCCESS(Status))
556 {
557 /* Create the new session */
560 MuSessionId,
561 sizeof(*MuSessionId));
562 if (!NT_SUCCESS(Status))
563 {
564 DPRINT1("SMSS: Session space creation failed\n");
566 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
567 return Status;
568 }
569 AttachedSessionId = *MuSessionId;
570
571 /*
572 * Start Win32k.sys on this session. Use a hardcoded value
573 * instead of the Kmode one...
574 */
576 L"\\SystemRoot\\System32\\win32k.sys");
579 sizeof(DestinationString));
580 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
582 if (!NT_SUCCESS(Status))
583 {
584 DPRINT1("SMSS: Load of WIN32K failed.\n");
585 return Status;
586 }
587 }
588 }
589 }
590
591 /* Next entry */
592 NextEntry = NextEntry->Flink;
593 }
594
595 /* Now parse the required subsystem list */
596 NextEntry = SmpSubSystemsToLoad.Flink;
597 while (NextEntry != &SmpSubSystemsToLoad)
598 {
599 /* Get each entry and check if it's the internal debug or not */
601 if (_wcsicmp(RegEntry->Name.Buffer, L"Debug") == 0)
602 {
603 /* Load the internal debug system */
605 *MuSessionId,
606 ProcessId,
608 }
609 else
610 {
611 /* Load the required subsystem */
613 *MuSessionId,
614 ProcessId,
616 }
617 if (!NT_SUCCESS(Status))
618 {
619 DPRINT1("SMSS: Subsystem execute failed (%wZ)\n", &RegEntry->Value);
620 return Status;
621 }
622
623 /* Move to the next entry */
624 NextEntry = NextEntry->Flink;
625 }
626
627 /* Process the "Execute" list now */
628 NextEntry = SmpExecuteList.Blink;
629 if (NextEntry != &SmpExecuteList)
630 {
631 /* Get the custom initial command */
633
634 /* Write the initial command and wait for 5 seconds (why??!) */
635 *InitialCommand = RegEntry->Name;
636 Timeout.QuadPart = -50000000;
638 }
639 else
640 {
641 /* Use the default Winlogon initial command */
642 RtlInitUnicodeString(InitialCommand, L"winlogon.exe");
644
645 /* Check if there's a debugger for Winlogon */
646 Status2 = LdrQueryImageFileExecutionOptions(InitialCommand,
647 L"Debugger",
648 REG_SZ,
650 sizeof(InitialCommandBuffer) -
651 InitialCommand->Length,
652 NULL);
653 if ((NT_SUCCESS(Status2)) && (InitialCommandBuffer[0]))
654 {
655 /* Put the debugger string with the Winlogon string */
657 RtlStringCbCatW(InitialCommandBuffer, sizeof(InitialCommandBuffer), InitialCommand->Buffer);
659 }
660 }
661
662 /* Finally check if there was a custom initial command */
663 NextEntry = SmpExecuteList.Flink;
664 while (NextEntry != &SmpExecuteList)
665 {
666 /* Execute each one */
668 SmpExecuteCommand(&RegEntry->Name, *MuSessionId, NULL, 0);
669 NextEntry = NextEntry->Flink;
670 }
671
672 /* Return status */
673 return Status;
674}
#define SystemExtendServiceTableInformation
Definition: DriverTester.h:35
#define REG_SZ
Definition: layer.c:22
NTSTATUS NTAPI LdrQueryImageFileExecutionOptions(_In_ PUNICODE_STRING SubKey, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:389
@ SystemSessionCreate
Definition: extypes.h:264
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1921
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
Definition: wait.c:876
#define UNICODE_NULL
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
#define L(x)
Definition: ntvdm.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
LIST_ENTRY SmpSubSystemList
Definition: sminit.c:22
LIST_ENTRY SmpSubSystemsToLoad
Definition: sminit.c:22
LIST_ENTRY SmpExecuteList
Definition: sminit.c:23
VOID NTAPI SmpTranslateSystemPartitionInformation(VOID)
Definition: sminit.c:811
LIST_ENTRY SmpSetupExecuteList
Definition: sminit.c:19
NTSTATUS NTAPI SmpExecuteCommand(IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
Definition: smss.c:210
#define SMP_DEBUG_FLAG
Definition: smss.h:44
#define SMP_SUBSYSTEM_FLAG
Definition: smss.h:47
WCHAR InitialCommandBuffer[256]
Definition: smsubsys.c:23
base of all file and directory entries
Definition: entries.h:83
Registry entry.
Definition: regfs.h:31
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by SmpLoadDataFromRegistry(), and SmpStartCsr().

◆ SmpLocateKnownSubSysByCid()

PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByCid ( IN PCLIENT_ID  ClientId)

Definition at line 68 of file smsubsys.c.

69{
70 PSMP_SUBSYSTEM Subsystem = NULL;
71 PLIST_ENTRY NextEntry;
72
73 /* Lock the subsystem database */
75
76 /* Loop each subsystem in the database */
77 NextEntry = SmpKnownSubSysHead.Flink;
78 while (NextEntry != &SmpKnownSubSysHead)
79 {
80 /* Check if this one matches the client ID and is still valid */
81 Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
82 if ((*(PULONGLONG)&Subsystem->ClientId == *(PULONGLONG)ClientId) &&
83 !(Subsystem->Terminating))
84 {
85 /* Add a reference and return it */
86 Subsystem->ReferenceCount++;
87 break;
88 }
89
90 /* Reset the current pointer and keep searching */
91 Subsystem = NULL;
92 NextEntry = NextEntry->Flink;
93 }
94
95 /* Release the lock and return the subsystem we found */
97 return Subsystem;
98}
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151

Referenced by SmpHandleConnectionRequest().

◆ SmpLocateKnownSubSysByType()

PSMP_SUBSYSTEM NTAPI SmpLocateKnownSubSysByType ( IN ULONG  MuSessionId,
IN ULONG  ImageType 
)

Definition at line 102 of file smsubsys.c.

104{
105 PSMP_SUBSYSTEM Subsystem = NULL;
106 PLIST_ENTRY NextEntry;
107
108 /* Lock the subsystem database */
110
111 /* Loop each subsystem in the database */
112 NextEntry = SmpKnownSubSysHead.Flink;
113 while (NextEntry != &SmpKnownSubSysHead)
114 {
115 /* Check if this one matches the image and uID, and is still valid */
116 Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry);
117 if ((Subsystem->ImageType == ImageType) &&
118 !(Subsystem->Terminating) &&
119 (Subsystem->MuSessionId == MuSessionId))
120 {
121 /* Return it referenced for the caller */
122 Subsystem->ReferenceCount++;
123 break;
124 }
125
126 /* Reset the current pointer and keep searching */
127 Subsystem = NULL;
128 NextEntry = NextEntry->Flink;
129 }
130
131 /* Release the lock and return the subsystem we found */
133 return Subsystem;
134}
ImageType
Definition: gdiplusenums.h:193

Referenced by SmpHandleConnectionRequest(), SmpLoadSubSystem(), and SmpSbCreateSession().

Variable Documentation

◆ InitialCommandBuffer

WCHAR InitialCommandBuffer[256]

Definition at line 23 of file smsubsys.c.

Referenced by SmpLoadSubSystemsForMuSession().

◆ RegPosixSingleInstance

BOOLEAN RegPosixSingleInstance

Definition at line 22 of file smsubsys.c.

Referenced by SmpConfigureSubSystems().

◆ SmpKnownSubSysHead

◆ SmpKnownSubSysLock

◆ SmpWindowsSubSysProcess

HANDLE SmpWindowsSubSysProcess

Definition at line 20 of file smsubsys.c.

Referenced by SmpInit(), and SmpLoadSubSystem().

◆ SmpWindowsSubSysProcessId

HANDLE SmpWindowsSubSysProcessId

Definition at line 21 of file smsubsys.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystem().