320 lines
10 KiB
C
320 lines
10 KiB
C
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
smss.c
|
|
|
|
Abstract:
|
|
|
|
|
|
Author:
|
|
|
|
Mark Lucovsky (markl) 04-Oct-1989
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "smsrvp.h"
|
|
|
|
#if defined(REMOTE_BOOT)
|
|
char SmpFormatKeyword[] = "NETBOOTFORMAT";
|
|
char SmpDisconnectedKeyword[] = "NETBOOTDISCONNECTED";
|
|
char SmpNetbootKeyword[] = "NETBOOT";
|
|
char SmpHalKeyword[] = "NETBOOTHAL";
|
|
|
|
BOOLEAN SmpAutoFormat = FALSE;
|
|
BOOLEAN SmpNetboot = FALSE;
|
|
BOOLEAN SmpNetbootDisconnected = FALSE;
|
|
char SmpHalName[MAX_HAL_NAME_LENGTH + 1] = "";
|
|
#endif // defined(REMOTE_BOOT)
|
|
|
|
void
|
|
SmpTerminate(
|
|
ULONG_PTR Parameters[]
|
|
);
|
|
|
|
EXCEPTION_DISPOSITION
|
|
SmpUnhandledExceptionFilter(
|
|
struct _EXCEPTION_POINTERS *ExceptionInfo,
|
|
ULONG_PTR Parameters[]
|
|
);
|
|
|
|
void
|
|
__cdecl main(
|
|
int argc,
|
|
char *argv[],
|
|
char *envp[],
|
|
ULONG DebugParameter OPTIONAL
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
KPRIORITY SetBasePriority;
|
|
UNICODE_STRING InitialCommand, DebugInitialCommand, UnicodeParameter;
|
|
HANDLE ProcessHandles[ 2 ];
|
|
ULONG_PTR Parameters[ 4 ];
|
|
PROCESS_BASIC_INFORMATION ProcessInfo;
|
|
ULONG MuSessionId = 0; // First instance (console) has MuSessionId = 0
|
|
#if defined(REMOTE_BOOT)
|
|
int TmpArgc;
|
|
#endif // defined(REMOTE_BOOT)
|
|
|
|
RtlSetProcessIsCritical(TRUE, NULL, TRUE);
|
|
RtlSetThreadIsCritical(TRUE, NULL, TRUE);
|
|
|
|
SetBasePriority = FOREGROUND_BASE_PRIORITY+2;
|
|
|
|
Status = NtSetInformationProcess( NtCurrentProcess(),
|
|
ProcessBasePriority,
|
|
(PVOID) &SetBasePriority,
|
|
sizeof( SetBasePriority )
|
|
);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
#if defined(REMOTE_BOOT)
|
|
TmpArgc = 1;
|
|
while (TmpArgc < argc) {
|
|
if (!strcmp(argv[TmpArgc], SmpFormatKeyword)) {
|
|
SmpAutoFormat = TRUE;
|
|
}
|
|
else if (!strcmp(argv[TmpArgc], SmpNetbootKeyword)) {
|
|
SmpNetboot = TRUE;
|
|
}
|
|
else if (!strcmp(argv[TmpArgc], SmpDisconnectedKeyword)) {
|
|
SmpNetbootDisconnected = TRUE;
|
|
}
|
|
else if (!strcmp(argv[TmpArgc], SmpHalKeyword)) {
|
|
TmpArgc++;
|
|
if (TmpArgc == argc) {
|
|
break;
|
|
}
|
|
memset(SmpHalName, 0x0, sizeof(SmpHalName));
|
|
strcpy(SmpHalName, argv[TmpArgc]);
|
|
}
|
|
TmpArgc++;
|
|
}
|
|
#endif // defined(REMOTE_BOOT)
|
|
|
|
if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR) DebugParameter )) {
|
|
SmpDebug = DebugParameter;
|
|
}
|
|
|
|
try {
|
|
Parameters[ 0 ] = (ULONG_PTR)&UnicodeParameter;
|
|
Parameters[ 1 ] = 0;
|
|
Parameters[ 2 ] = 0;
|
|
Parameters[ 3 ] = 0;
|
|
|
|
|
|
Status = SmpInit( &InitialCommand, &ProcessHandles[ 0 ] );
|
|
if (!NT_SUCCESS( Status )) {
|
|
KdPrint(( "SMSS: SmpInit return failure - Status == %x\n", Status ));
|
|
RtlInitUnicodeString( &UnicodeParameter, L"Session Manager Initialization" );
|
|
Parameters[ 1 ] = (ULONG)Status;
|
|
|
|
} else {
|
|
SYSTEM_FLAGS_INFORMATION FlagInfo;
|
|
|
|
NtQuerySystemInformation( SystemFlagsInformation,
|
|
&FlagInfo,
|
|
sizeof( FlagInfo ),
|
|
NULL
|
|
);
|
|
if (FlagInfo.Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX) ) {
|
|
DebugInitialCommand.MaximumLength = InitialCommand.Length + 64;
|
|
DebugInitialCommand.Length = 0;
|
|
DebugInitialCommand.Buffer = RtlAllocateHeap( RtlProcessHeap(),
|
|
MAKE_TAG( INIT_TAG ),
|
|
DebugInitialCommand.MaximumLength
|
|
);
|
|
if (FlagInfo.Flags & FLG_ENABLE_CSRDEBUG) {
|
|
|
|
RtlAppendUnicodeToString( &DebugInitialCommand, L"ntsd -p -1 -d " );
|
|
}
|
|
else {
|
|
RtlAppendUnicodeToString( &DebugInitialCommand, L"ntsd -d " );
|
|
}
|
|
|
|
if (FlagInfo.Flags & FLG_DEBUG_INITIAL_COMMAND_EX ) {
|
|
RtlAppendUnicodeToString( &DebugInitialCommand, L"-g -x " );
|
|
}
|
|
|
|
RtlAppendUnicodeStringToString( &DebugInitialCommand, &InitialCommand );
|
|
InitialCommand = DebugInitialCommand;
|
|
}
|
|
|
|
Status = SmpExecuteInitialCommand( 0L, &InitialCommand, &ProcessHandles[ 1 ], NULL );
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
|
|
//
|
|
// Detach the session manager from the session space as soon as
|
|
// we have executed the initial command (winlogon).
|
|
//
|
|
|
|
PVOID State;
|
|
|
|
Status = SmpAcquirePrivilege( SE_LOAD_DRIVER_PRIVILEGE, &State );
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
|
|
//
|
|
// If we are attached to a session space, leave it
|
|
// so we can create a new one
|
|
//
|
|
if( (AttachedSessionId != (-1)) ) {
|
|
Status = NtSetSystemInformation(
|
|
SystemSessionDetach,
|
|
(PVOID)&AttachedSessionId,
|
|
sizeof(MuSessionId)
|
|
);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
AttachedSessionId = (-1);
|
|
}
|
|
|
|
SmpReleasePrivilege( State );
|
|
}
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
Status = NtWaitForMultipleObjects( 2,
|
|
ProcessHandles,
|
|
WaitAny,
|
|
FALSE,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
if (Status == STATUS_WAIT_0) {
|
|
RtlInitUnicodeString( &UnicodeParameter, L"Windows SubSystem" );
|
|
Status = NtQueryInformationProcess( ProcessHandles[ 0 ],
|
|
ProcessBasicInformation,
|
|
&ProcessInfo,
|
|
sizeof( ProcessInfo ),
|
|
NULL
|
|
);
|
|
|
|
KdPrint(( "SMSS: Windows subsystem terminated when it wasn't supposed to.\n" ));
|
|
} else {
|
|
RtlInitUnicodeString( &UnicodeParameter, L"Windows Logon Process" );
|
|
if (Status == STATUS_WAIT_1) {
|
|
Status = NtQueryInformationProcess( ProcessHandles[ 1 ],
|
|
ProcessBasicInformation,
|
|
&ProcessInfo,
|
|
sizeof( ProcessInfo ),
|
|
NULL
|
|
);
|
|
} else {
|
|
ProcessInfo.ExitStatus = Status;
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
KdPrint(( "SMSS: Initial command '%wZ' terminated when it wasn't supposed to.\n", &InitialCommand ));
|
|
}
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
Parameters[ 1 ] = (ULONG)ProcessInfo.ExitStatus;
|
|
} else {
|
|
Parameters[ 1 ] = (ULONG)STATUS_UNSUCCESSFUL;
|
|
}
|
|
}
|
|
|
|
} except( SmpUnhandledExceptionFilter( GetExceptionInformation(), Parameters ) ) {
|
|
/* not reached */
|
|
}
|
|
|
|
SmpTerminate(Parameters);
|
|
/* not reached */
|
|
}
|
|
|
|
void
|
|
SmpTerminate(
|
|
ULONG_PTR Parameters[]
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG Response;
|
|
BOOLEAN WasEnabled;
|
|
|
|
//
|
|
// We are hosed, so raise a fatal system error to shutdown the system.
|
|
// (Basically a user mode KeBugCheck).
|
|
//
|
|
|
|
Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
|
|
(BOOLEAN)TRUE,
|
|
TRUE,
|
|
&WasEnabled
|
|
);
|
|
|
|
if (Status == STATUS_NO_TOKEN) {
|
|
|
|
//
|
|
// No thread token, use the process token.
|
|
//
|
|
|
|
Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
|
|
(BOOLEAN)TRUE,
|
|
FALSE,
|
|
&WasEnabled
|
|
);
|
|
}
|
|
|
|
|
|
Status = NtRaiseHardError( STATUS_SYSTEM_PROCESS_TERMINATED,
|
|
4,
|
|
1,
|
|
Parameters,
|
|
OptionShutdownSystem,
|
|
&Response
|
|
);
|
|
|
|
//
|
|
// If this returns, give up.
|
|
//
|
|
|
|
NtTerminateProcess( NtCurrentProcess(), Status );
|
|
}
|
|
|
|
|
|
EXCEPTION_DISPOSITION
|
|
SmpUnhandledExceptionFilter(
|
|
struct _EXCEPTION_POINTERS *ExceptionInfo,
|
|
ULONG_PTR Parameters[]
|
|
)
|
|
{
|
|
UNICODE_STRING ExUnicodeParameter;
|
|
|
|
#if DBG
|
|
DbgPrint( "SMSS: Unhandled exception - Status == %x IP == %x\n",
|
|
ExceptionInfo->ExceptionRecord->ExceptionCode,
|
|
ExceptionInfo->ExceptionRecord->ExceptionAddress
|
|
);
|
|
DbgPrint( " Memory Address: %x Read/Write: %x\n",
|
|
ExceptionInfo->ExceptionRecord->ExceptionInformation[ 0 ],
|
|
ExceptionInfo->ExceptionRecord->ExceptionInformation[ 1 ]
|
|
);
|
|
|
|
DbgBreakPoint();
|
|
#endif
|
|
|
|
RtlInitUnicodeString( &ExUnicodeParameter, L"Unhandled Exception in Session Manager" );
|
|
Parameters[ 0 ] = (ULONG_PTR)&ExUnicodeParameter;
|
|
Parameters[ 1 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionCode;
|
|
Parameters[ 2 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
|
|
Parameters[ 3 ] = (ULONG_PTR)ExceptionInfo->ContextRecord;
|
|
|
|
//
|
|
// SmpTerminate will raise a hard error with the exception info still valid.
|
|
//
|
|
|
|
SmpTerminate(Parameters);
|
|
|
|
// not reached
|
|
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
|
}
|