@@ -514,6 +514,74 @@ _main(IN INT argc,
514514 }
515515 SmpReleasePrivilege (State );
516516
517+ /*
518+ * Bring up a second session (MuSession 1). smss is the session leader
519+ * and is now sessionless again, so it can create another kernel session,
520+ * load that session's subsystems (its own csrss) and launch its initial
521+ * command (winlogon) - exactly what the SB API SmpStartCsr does for a
522+ * remote session-create request, just driven directly here.
523+ *
524+ * Gated behind HKLM\SYSTEM\CCS\Control\Session Manager:EnableSecondSession
525+ * (DWORD, default 0): the kernel session create, the per-session win32k
526+ * load (session-image reuse path) and the per-session object namespaces
527+ * all work, but session 1's csrss still trips deep per-session win32k GUI
528+ * issues, so it is opt-in until that is finished.
529+ */
530+ {
531+ ULONG EnableSecondSession = 0 ;
532+ RTL_QUERY_REGISTRY_TABLE SecondSessionQueryTable [2 ];
533+
534+ RtlZeroMemory (SecondSessionQueryTable , sizeof (SecondSessionQueryTable ));
535+ SecondSessionQueryTable [0 ].Flags = RTL_QUERY_REGISTRY_DIRECT ;
536+ SecondSessionQueryTable [0 ].Name = L"EnableSecondSession" ;
537+ SecondSessionQueryTable [0 ].EntryContext = & EnableSecondSession ;
538+ SecondSessionQueryTable [0 ].DefaultType = REG_DWORD ;
539+ SecondSessionQueryTable [0 ].DefaultData = & EnableSecondSession ;
540+ SecondSessionQueryTable [0 ].DefaultLength = sizeof (EnableSecondSession );
541+ RtlQueryRegistryValues (RTL_REGISTRY_CONTROL ,
542+ L"Session Manager" ,
543+ SecondSessionQueryTable ,
544+ NULL ,
545+ NULL );
546+
547+ if (EnableSecondSession )
548+ {
549+ ULONG Session1Id = 1 ;
550+ HANDLE Session1WinSubSysPid = NULL ;
551+ HANDLE Session1Command = NULL ;
552+ UNICODE_STRING Session1InitialCommand ;
553+
554+ RtlInitEmptyUnicodeString (& Session1InitialCommand , NULL , 0 );
555+
556+ DPRINT1 ("SMSS: Bringing up session %lu\n" , Session1Id );
557+ Status = SmpLoadSubSystemsForMuSession (& Session1Id ,
558+ & Session1WinSubSysPid ,
559+ & Session1InitialCommand );
560+ if (!NT_SUCCESS (Status ))
561+ {
562+ DPRINT1 ("SMSS: SmpLoadSubSystemsForMuSession(%lu) failed - 0x%x\n" ,
563+ Session1Id , Status );
564+ }
565+ else
566+ {
567+ Status = SmpExecuteInitialCommand (Session1Id ,
568+ & Session1InitialCommand ,
569+ & Session1Command ,
570+ NULL );
571+ if (!NT_SUCCESS (Status ))
572+ {
573+ DPRINT1 ("SMSS: session %lu initial command failed - 0x%x\n" ,
574+ Session1Id , Status );
575+ }
576+ else
577+ {
578+ DPRINT1 ("SMSS: session %lu is up and running\n" , Session1Id );
579+ if (Session1Command ) NtClose (Session1Command );
580+ }
581+ }
582+ } /* if (EnableSecondSession) */
583+ }
584+
517585 /* Wait on either CSRSS or Winlogon to die */
518586 Status = NtWaitForMultipleObjects (RTL_NUMBER_OF (Handles ),
519587 Handles ,
0 commit comments