Leaked source code of windows server 2003
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.

300 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. RtlSetProcessIsCritical(TRUE, NULL, TRUE);
  46. RtlSetThreadIsCritical(TRUE, NULL, TRUE);
  47. SetBasePriority = FOREGROUND_BASE_PRIORITY+2;
  48. Status = NtSetInformationProcess( NtCurrentProcess(),
  49. ProcessBasePriority,
  50. (PVOID) &SetBasePriority,
  51. sizeof( SetBasePriority )
  52. );
  53. ASSERT(NT_SUCCESS(Status));
  54. if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR) DebugParameter )) {
  55. SmpDebug = DebugParameter;
  56. }
  57. try {
  58. Parameters[ 0 ] = (ULONG_PTR)&UnicodeParameter;
  59. Parameters[ 1 ] = 0;
  60. Parameters[ 2 ] = 0;
  61. Parameters[ 3 ] = 0;
  62. Status = SmpInit( &InitialCommand, &ProcessHandles[ 0 ] );
  63. if (!NT_SUCCESS( Status )) {
  64. KdPrint(( "SMSS: SmpInit return failure - Status == %x\n", Status ));
  65. RtlInitUnicodeString( &UnicodeParameter, L"Session Manager Initialization" );
  66. Parameters[ 1 ] = (ULONG)Status;
  67. } else {
  68. SYSTEM_FLAGS_INFORMATION FlagInfo;
  69. Status = NtQuerySystemInformation( SystemFlagsInformation,
  70. &FlagInfo,
  71. sizeof( FlagInfo ),
  72. NULL);
  73. ASSERT(NT_SUCCESS(Status));
  74. if (FlagInfo.Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX) ) {
  75. DebugInitialCommand.MaximumLength = InitialCommand.Length + 64;
  76. DebugInitialCommand.Length = 0;
  77. DebugInitialCommand.Buffer = RtlAllocateHeap( RtlProcessHeap(),
  78. MAKE_TAG( INIT_TAG ),
  79. DebugInitialCommand.MaximumLength
  80. );
  81. if (DebugInitialCommand.Buffer == NULL) {
  82. Status = STATUS_NO_MEMORY;
  83. KdPrint(( "SMSS: SmpInit heap allocation failed\n"));
  84. } else {
  85. if (FlagInfo.Flags & FLG_ENABLE_CSRDEBUG) {
  86. RtlAppendUnicodeToString( &DebugInitialCommand, L"ntsd -isd -p -1 -d " );
  87. } else {
  88. RtlAppendUnicodeToString( &DebugInitialCommand, L"ntsd -isd -d " );
  89. }
  90. if (FlagInfo.Flags & FLG_DEBUG_INITIAL_COMMAND_EX ) {
  91. RtlAppendUnicodeToString( &DebugInitialCommand, L"-g -x " );
  92. }
  93. RtlAppendUnicodeStringToString( &DebugInitialCommand, &InitialCommand );
  94. InitialCommand = DebugInitialCommand;
  95. }
  96. }
  97. if (NT_SUCCESS( Status )) {
  98. Status = SmpExecuteInitialCommand( 0L, &InitialCommand, &ProcessHandles[ 1 ], NULL );
  99. }
  100. if (NT_SUCCESS( Status )) {
  101. //
  102. // Detach the session manager from the session space as soon as
  103. // we have executed the initial command (winlogon).
  104. //
  105. PVOID State;
  106. Status = SmpAcquirePrivilege( SE_LOAD_DRIVER_PRIVILEGE, &State );
  107. if (NT_SUCCESS( Status )) {
  108. //
  109. // If we are attached to a session space, leave it
  110. // so we can create a new one
  111. //
  112. if( (AttachedSessionId != (-1)) ) {
  113. Status = NtSetSystemInformation(
  114. SystemSessionDetach,
  115. (PVOID)&AttachedSessionId,
  116. sizeof(MuSessionId)
  117. );
  118. ASSERT(NT_SUCCESS(Status));
  119. AttachedSessionId = (-1);
  120. }
  121. SmpReleasePrivilege( State );
  122. }
  123. }
  124. if (NT_SUCCESS( Status )) {
  125. Status = NtWaitForMultipleObjects( 2,
  126. ProcessHandles,
  127. WaitAny,
  128. FALSE,
  129. NULL
  130. );
  131. }
  132. if (Status == STATUS_WAIT_0) {
  133. RtlInitUnicodeString( &UnicodeParameter, L"Windows SubSystem" );
  134. Status = NtQueryInformationProcess( ProcessHandles[ 0 ],
  135. ProcessBasicInformation,
  136. &ProcessInfo,
  137. sizeof( ProcessInfo ),
  138. NULL
  139. );
  140. KdPrint(( "SMSS: Windows subsystem terminated when it wasn't supposed to.\n" ));
  141. } else {
  142. RtlInitUnicodeString( &UnicodeParameter, L"Windows Logon Process" );
  143. if (Status == STATUS_WAIT_1) {
  144. Status = NtQueryInformationProcess( ProcessHandles[ 1 ],
  145. ProcessBasicInformation,
  146. &ProcessInfo,
  147. sizeof( ProcessInfo ),
  148. NULL
  149. );
  150. } else {
  151. ProcessInfo.ExitStatus = Status;
  152. Status = STATUS_SUCCESS;
  153. }
  154. KdPrint(( "SMSS: Initial command '%wZ' terminated when it wasn't supposed to.\n", &InitialCommand ));
  155. }
  156. if (NT_SUCCESS( Status )) {
  157. Parameters[ 1 ] = (ULONG)ProcessInfo.ExitStatus;
  158. } else {
  159. Parameters[ 1 ] = (ULONG)STATUS_UNSUCCESSFUL;
  160. }
  161. }
  162. } except( SmpUnhandledExceptionFilter( GetExceptionInformation(), Parameters ) ) {
  163. /* not reached */
  164. }
  165. SmpTerminate(Parameters);
  166. /* not reached */
  167. }
  168. void
  169. SmpTerminate(
  170. ULONG_PTR Parameters[]
  171. )
  172. {
  173. NTSTATUS Status;
  174. ULONG Response;
  175. BOOLEAN WasEnabled;
  176. //
  177. // We are hosed, so raise a fatal system error to shutdown the system.
  178. // (Basically a user mode KeBugCheck).
  179. //
  180. Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
  181. (BOOLEAN)TRUE,
  182. TRUE,
  183. &WasEnabled
  184. );
  185. if (Status == STATUS_NO_TOKEN) {
  186. //
  187. // No thread token, use the process token.
  188. //
  189. Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
  190. (BOOLEAN)TRUE,
  191. FALSE,
  192. &WasEnabled
  193. );
  194. }
  195. Status = NtRaiseHardError( STATUS_SYSTEM_PROCESS_TERMINATED,
  196. 4,
  197. 1,
  198. Parameters,
  199. OptionShutdownSystem,
  200. &Response
  201. );
  202. //
  203. // If this returns, give up.
  204. //
  205. NtTerminateProcess( NtCurrentProcess(), Status );
  206. }
  207. EXCEPTION_DISPOSITION
  208. SmpUnhandledExceptionFilter(
  209. struct _EXCEPTION_POINTERS *ExceptionInfo,
  210. ULONG_PTR Parameters[]
  211. )
  212. {
  213. UNICODE_STRING ExUnicodeParameter;
  214. #if DBG
  215. DbgPrint( "SMSS: Unhandled exception - Status == %x IP == %x\n",
  216. ExceptionInfo->ExceptionRecord->ExceptionCode,
  217. ExceptionInfo->ExceptionRecord->ExceptionAddress
  218. );
  219. DbgPrint( " Memory Address: %x Read/Write: %x\n",
  220. ExceptionInfo->ExceptionRecord->ExceptionInformation[ 0 ],
  221. ExceptionInfo->ExceptionRecord->ExceptionInformation[ 1 ]
  222. );
  223. DbgBreakPoint();
  224. #endif
  225. RtlInitUnicodeString( &ExUnicodeParameter, L"Unhandled Exception in Session Manager" );
  226. Parameters[ 0 ] = (ULONG_PTR)&ExUnicodeParameter;
  227. Parameters[ 1 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionCode;
  228. Parameters[ 2 ] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
  229. Parameters[ 3 ] = (ULONG_PTR)ExceptionInfo->ContextRecord;
  230. //
  231. // SmpTerminate will raise a hard error with the exception info still valid.
  232. //
  233. SmpTerminate(Parameters);
  234. // not reached
  235. return EXCEPTION_EXECUTE_HANDLER;
  236. }