Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
10 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. smss.c
  5. Abstract:
  6. Author:
  7. Mark Lucovsky (markl) 04-Oct-1989
  8. Revision History:
  9. --*/
  10. #include "smsrvp.h"
  11. #if defined(REMOTE_BOOT)
  12. char SmpFormatKeyword[] = "NETBOOTFORMAT";
  13. char SmpDisconnectedKeyword[] = "NETBOOTDISCONNECTED";
  14. char SmpNetbootKeyword[] = "NETBOOT";
  15. char SmpHalKeyword[] = "NETBOOTHAL";
  16. BOOLEAN SmpAutoFormat = FALSE;
  17. BOOLEAN SmpNetboot = FALSE;
  18. BOOLEAN SmpNetbootDisconnected = FALSE;
  19. char SmpHalName[MAX_HAL_NAME_LENGTH + 1] = "";
  20. #endif // defined(REMOTE_BOOT)
  21. void
  22. SmpTerminate(
  23. ULONG_PTR Parameters[]
  24. );
  25. EXCEPTION_DISPOSITION
  26. SmpUnhandledExceptionFilter(
  27. struct _EXCEPTION_POINTERS *ExceptionInfo,
  28. ULONG_PTR Parameters[]
  29. );
  30. void
  31. __cdecl main(
  32. int argc,
  33. char *argv[],
  34. char *envp[],
  35. ULONG DebugParameter OPTIONAL
  36. )
  37. {
  38. NTSTATUS Status;
  39. KPRIORITY SetBasePriority;
  40. UNICODE_STRING InitialCommand, DebugInitialCommand, UnicodeParameter;
  41. HANDLE ProcessHandles[ 2 ];
  42. ULONG_PTR Parameters[ 4 ];
  43. PROCESS_BASIC_INFORMATION ProcessInfo;
  44. ULONG MuSessionId = 0; // First instance (console) has MuSessionId = 0
  45. #if defined(REMOTE_BOOT)
  46. int TmpArgc;
  47. #endif // defined(REMOTE_BOOT)
  48. RtlSetProcessIsCritical(TRUE, NULL, TRUE);
  49. RtlSetThreadIsCritical(TRUE, NULL, TRUE);
  50. SetBasePriority = FOREGROUND_BASE_PRIORITY+2;
  51. Status = NtSetInformationProcess( NtCurrentProcess(),
  52. ProcessBasePriority,
  53. (PVOID) &SetBasePriority,
  54. sizeof( SetBasePriority )
  55. );
  56. ASSERT(NT_SUCCESS(Status));
  57. #if defined(REMOTE_BOOT)
  58. TmpArgc = 1;
  59. while (TmpArgc < argc) {
  60. if (!strcmp(argv[TmpArgc], SmpFormatKeyword)) {
  61. SmpAutoFormat = TRUE;
  62. }
  63. else if (!strcmp(argv[TmpArgc], SmpNetbootKeyword)) {
  64. SmpNetboot = TRUE;
  65. }
  66. else if (!strcmp(argv[TmpArgc], SmpDisconnectedKeyword)) {
  67. SmpNetbootDisconnected = TRUE;
  68. }
  69. else if (!strcmp(argv[TmpArgc], SmpHalKeyword)) {
  70. TmpArgc++;
  71. if (TmpArgc == argc) {
  72. break;
  73. }
  74. memset(SmpHalName, 0x0, sizeof(SmpHalName));
  75. strcpy(SmpHalName, argv[TmpArgc]);
  76. }
  77. TmpArgc++;
  78. }
  79. #endif // defined(REMOTE_BOOT)
  80. if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR) DebugParameter )) {
  81. SmpDebug = DebugParameter;
  82. }
  83. try {
  84. Parameters[ 0 ] = (ULONG_PTR)&UnicodeParameter;
  85. Parameters[ 1 ] = 0;
  86. Parameters[ 2 ] = 0;
  87. Parameters[ 3 ] = 0;
  88. Status = SmpInit( &InitialCommand, &ProcessHandles[ 0 ] );
  89. if (!NT_SUCCESS( Status )) {
  90. KdPrint(( "SMSS: SmpInit return failure - Status == %x\n", Status ));
  91. RtlInitUnicodeString( &UnicodeParameter, L"Session Manager Initialization" );
  92. Parameters[ 1 ] = (ULONG)Status;
  93. } else {
  94. SYSTEM_FLAGS_INFORMATION FlagInfo;
  95. NtQuerySystemInformation( SystemFlagsInformation,
  96. &FlagInfo,
  97. sizeof( FlagInfo ),
  98. NULL
  99. );
  100. if (FlagInfo.Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX) ) {
  101. DebugInitialCommand.MaximumLength = InitialCommand.Length + 64;
  102. DebugInitialCommand.Length = 0;
  103. DebugInitialCommand.Buffer = RtlAllocateHeap( RtlProcessHeap(),
  104. MAKE_TAG( INIT_TAG ),
  105. DebugInitialCommand.MaximumLength
  106. );
  107. if (FlagInfo.Flags & FLG_ENABLE_CSRDEBUG) {
  108. RtlAppendUnicodeToString( &DebugInitialCommand, L"ntsd -p -1 -d " );
  109. }
  110. else {
  111. RtlAppendUnicodeToString( &DebugInitialCommand, L"ntsd -d " );
  112. }
  113. if (FlagInfo.Flags & FLG_DEBUG_INITIAL_COMMAND_EX ) {
  114. RtlAppendUnicodeToString( &DebugInitialCommand, L"-g -x " );
  115. }
  116. RtlAppendUnicodeStringToString( &DebugInitialCommand, &InitialCommand );
  117. InitialCommand = DebugInitialCommand;
  118. }
  119. Status = SmpExecuteInitialCommand( 0L, &InitialCommand, &ProcessHandles[ 1 ], NULL );
  120. if (NT_SUCCESS( Status )) {
  121. //
  122. // Detach the session manager from the session space as soon as
  123. // we have executed the initial command (winlogon).
  124. //
  125. PVOID State;
  126. Status = SmpAcquirePrivilege( SE_LOAD_DRIVER_PRIVILEGE, &State );
  127. if (NT_SUCCESS( Status )) {
  128. //
  129. // If we are attached to a session space, leave it
  130. // so we can create a new one
  131. //
  132. if( (AttachedSessionId != (-1)) ) {
  133. Status = NtSetSystemInformation(
  134. SystemSessionDetach,
  135. (PVOID)&AttachedSessionId,
  136. sizeof(MuSessionId)
  137. );
  138. ASSERT(NT_SUCCESS(Status));
  139. AttachedSessionId = (-1);
  140. }
  141. SmpReleasePrivilege( State );
  142. }
  143. }
  144. if (NT_SUCCESS( Status )) {
  145. Status = NtWaitForMultipleObjects( 2,
  146. ProcessHandles,
  147. WaitAny,
  148. FALSE,
  149. NULL
  150. );
  151. }
  152. if (Status == STATUS_WAIT_0) {
  153. RtlInitUnicodeString( &UnicodeParameter, L"Windows SubSystem" );
  154. Status = NtQueryInformationProcess( ProcessHandles[ 0 ],
  155. ProcessBasicInformation,
  156. &ProcessInfo,
  157. sizeof( ProcessInfo ),
  158. NULL
  159. );
  160. KdPrint(( "SMSS: Windows subsystem terminated when it wasn't supposed to.\n" ));
  161. } else {
  162. RtlInitUnicodeString( &UnicodeParameter, L"Windows Logon Process" );
  163. if (Status == STATUS_WAIT_1) {
  164. Status = NtQueryInformationProcess( ProcessHandles[ 1 ],
  165. ProcessBasicInformation,
  166. &ProcessInfo,
  167. sizeof( ProcessInfo ),
  168. NULL
  169. );
  170. } else {
  171. ProcessInfo.ExitStatus = Status;
  172. Status = STATUS_SUCCESS;
  173. }
  174. KdPrint(( "SMSS: Initial command '%wZ' terminated when it wasn't supposed to.\n", &InitialCommand ));
  175. }
  176. if (NT_SUCCESS( Status )) {
  177. Parameters[ 1 ] = (ULONG)ProcessInfo.ExitStatus;
  178. } else {
  179. Parameters[ 1 ] = (ULONG)STATUS_UNSUCCESSFUL;
  180. }
  181. }
  182. } except( SmpUnhandledExceptionFilter( GetExceptionInformation(), Parameters ) ) {
  183. /* not reached */
  184. }
  185. SmpTerminate(Parameters);
  186. /* not reached */
  187. }
  188. void
  189. SmpTerminate(
  190. ULONG_PTR Parameters[]
  191. )
  192. {
  193. NTSTATUS Status;
  194. ULONG Response;
  195. BOOLEAN WasEnabled;
  196. //
  197. // We are hosed, so raise a fatal system error to shutdown the system.
  198. // (Basically a user mode KeBugCheck).
  199. //
  200. Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
  201. (BOOLEAN)TRUE,
  202. TRUE,
  203. &WasEnabled
  204. );
  205. if (Status == STATUS_NO_TOKEN) {
  206. //
  207. // No thread token, use the process token.
  208. //
  209. Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
  210. (BOOLEAN)TRUE,
  211. FALSE,
  212. &WasEnabled
  213. );
  214. }
  215. Status = NtRaiseHardError( STATUS_SYSTEM_PROCESS_TERMINATED,
  216. 4,
  217. 1,
  218. Parameters,
  219. OptionShutdownSystem,
  220. &Response
  221. );
  222. //
  223. // If this returns, give up.
  224. //
  225. NtTerminateProcess( NtCurrentProcess(), Status );
  226. }
  227. EXCEPTION_DISPOSITION
  228. SmpUnhandledExceptionFilter(
  229. struct _EXCEPTION_POINTERS *ExceptionInfo,
  230. ULONG_PTR Parameters[]
  231. )
  232. {
  233. UNICODE_STRING ExUnicodeParameter;
  234. #if DBG
  235. DbgPrint( "SMSS: Unhandled exception - Status == %x IP == %x\n",
  236. ExceptionInfo->ExceptionRecord->ExceptionCode,
  237. ExceptionInfo->ExceptionRecord->ExceptionAddress
  238. );
  239. DbgPrint( " Memory Address: %x Read/Write: %x\n",
  240. ExceptionInfo->ExceptionRecord->ExceptionInformation[ 0 ],
  241. ExceptionInfo->ExceptionRecord->ExceptionInformation[ 1 ]
  242. );
  243. DbgBreakPoint();
  244. #endif
  245. RtlInitUnicodeString( &ExUnicodeParameter, L"Unhandled Exception in Session Manager" );
  246. Parameters[ 0 ] = (ULONG_PTR)&ExUnicodeParameter;
  247. Parameters[ 1 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionCode;
  248. Parameters[ 2 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
  249. Parameters[ 3 ] = (ULONG_PTR)ExceptionInfo->ContextRecord;
  250. //
  251. // SmpTerminate will raise a hard error with the exception info still valid.
  252. //
  253. SmpTerminate(Parameters);
  254. // not reached
  255. return EXCEPTION_EXECUTE_HANDLER;
  256. }