ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

smss.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Windows-Compatible Session Manager
00003  * LICENSE:         BSD 2-Clause License
00004  * FILE:            base/system/smss/smss.c
00005  * PURPOSE:         Main SMSS Code
00006  * PROGRAMMERS:     Alex Ionescu
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include "smss.h"
00012 #define NDEBUG
00013 #include "debug.h"
00014 
00015 /* GLOBALS ********************************************************************/
00016 
00017 UNICODE_STRING SmpSystemRoot;
00018 ULONG AttachedSessionId = -1;
00019 BOOLEAN SmpDebug, SmpEnableDots;
00020 HANDLE SmApiPort;
00021 HANDLE SmpInitialCommandProcessId;
00022 
00023 /* FUNCTIONS ******************************************************************/
00024 
00025 /* GCC's incompetence strikes again */
00026 VOID
00027 sprintf_nt(IN PCHAR Buffer,
00028            IN PCHAR Format,
00029            IN ...)
00030 {
00031     va_list ap;
00032     va_start(ap, Format);
00033     sprintf(Buffer, Format, ap);
00034     va_end(ap);
00035 }
00036 
00037 NTSTATUS
00038 NTAPI
00039 SmpExecuteImage(IN PUNICODE_STRING FileName,
00040                 IN PUNICODE_STRING Directory,
00041                 IN PUNICODE_STRING CommandLine,
00042                 IN ULONG MuSessionId,
00043                 IN ULONG Flags,
00044                 IN PRTL_USER_PROCESS_INFORMATION ProcessInformation)
00045 {
00046     PRTL_USER_PROCESS_INFORMATION ProcessInfo;
00047     NTSTATUS Status;
00048     RTL_USER_PROCESS_INFORMATION LocalProcessInfo;
00049     PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
00050 
00051     /* Use the input process information if we have it, otherwise use local */
00052     ProcessInfo = ProcessInformation;
00053     if (!ProcessInfo) ProcessInfo = &LocalProcessInfo;
00054 
00055     /* Create parameters for the target process */
00056     Status = RtlCreateProcessParameters(&ProcessParameters,
00057                                         FileName,
00058                                         SmpDefaultLibPath.Length ?
00059                                         &SmpDefaultLibPath : NULL,
00060                                         Directory,
00061                                         CommandLine,
00062                                         SmpDefaultEnvironment,
00063                                         NULL,
00064                                         NULL,
00065                                         NULL,
00066                                         0);
00067     if (!NT_SUCCESS(Status))
00068     {
00069         /* This is a pretty bad failure. ASSERT on checked builds and exit */
00070         ASSERTMSG(NT_SUCCESS(Status), "RtlCreateProcessParameters");
00071         DPRINT1("SMSS: RtlCreateProcessParameters failed for %wZ - Status == %lx\n",
00072                 FileName, Status);
00073         return Status;
00074     }
00075 
00076     /* Set the size field as required */
00077     ProcessInfo->Size = sizeof(RTL_USER_PROCESS_INFORMATION);
00078 
00079     /* Check if the debug flag was requested */
00080     if (Flags & SMP_DEBUG_FLAG)
00081     {
00082         /* Write it in the process parameters */
00083         ProcessParameters->DebugFlags = 1;
00084     }
00085     else
00086     {
00087         /* Otherwise inherit the flag that was passed to SMSS itself */
00088         ProcessParameters->DebugFlags = SmpDebug;
00089     }
00090 
00091     /* Subsystems get the first 1MB of memory reserved for DOS/IVT purposes */
00092     if (Flags & SMP_SUBSYSTEM_FLAG)
00093     {
00094         ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
00095     }
00096 
00097     /* And always force NX for anything that SMSS launches */
00098     ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_NX;
00099 
00100     /* Now create the process */
00101     Status = RtlCreateUserProcess(FileName,
00102                                   OBJ_CASE_INSENSITIVE,
00103                                   ProcessParameters,
00104                                   NULL,
00105                                   NULL,
00106                                   NULL,
00107                                   FALSE,
00108                                   NULL,
00109                                   NULL,
00110                                   ProcessInfo);
00111     RtlDestroyProcessParameters(ProcessParameters);
00112     if (!NT_SUCCESS(Status))
00113     {
00114         /* If we couldn't create it, fail back to the caller */
00115         DPRINT1("SMSS: Failed load of %wZ - Status  == %lx\n",
00116                 FileName, Status);
00117         return Status;
00118     }
00119 
00120     /* Associate a session with this process */
00121     Status = SmpSetProcessMuSessionId(ProcessInfo->ProcessHandle, MuSessionId);
00122 
00123     /* If the application is deferred (suspended), there's nothing to do */
00124     if (Flags & SMP_DEFERRED_FLAG) return Status;
00125 
00126     /* Otherwise, get ready to start it, but make sure it's a native app */
00127     if (ProcessInfo->ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE)
00128     {
00129         /* Resume it */
00130         NtResumeThread(ProcessInfo->ThreadHandle, NULL);
00131         if (!(Flags & SMP_ASYNC_FLAG))
00132         {
00133             /* Block on it unless Async was requested */
00134             NtWaitForSingleObject(ProcessInfo->ThreadHandle, FALSE, NULL);
00135         }
00136 
00137         /* It's up and running now, close our handles */
00138         NtClose(ProcessInfo->ThreadHandle);
00139         NtClose(ProcessInfo->ProcessHandle);
00140     }
00141     else
00142     {
00143         /* This image is invalid, so kill it, close our handles, and fail */
00144         Status = STATUS_INVALID_IMAGE_FORMAT;
00145         NtTerminateProcess(ProcessInfo->ProcessHandle, Status);
00146         NtWaitForSingleObject(ProcessInfo->ThreadHandle, 0, 0);
00147         NtClose(ProcessInfo->ThreadHandle);
00148         NtClose(ProcessInfo->ProcessHandle);
00149         DPRINT1("SMSS: Not an NT image - %wZ\n", FileName);
00150     }
00151 
00152     /* Return the outcome of the process create */
00153     return Status;
00154 }
00155 
00156 NTSTATUS
00157 NTAPI
00158 SmpInvokeAutoChk(IN PUNICODE_STRING FileName,
00159                  IN PUNICODE_STRING Directory,
00160                  IN PUNICODE_STRING Arguments,
00161                  IN ULONG Flags)
00162 {
00163     ANSI_STRING DestinationString;
00164     CHAR SourceString[256];
00165     UNICODE_STRING Destination;
00166     WCHAR Buffer[1024];
00167     BOOLEAN BootState, BootOkay, ShutdownOkay;
00168 
00169     /* Check if autochk should show dots (if the user booted with /SOS) */
00170     if (SmpQueryRegistrySosOption()) SmpEnableDots = FALSE;
00171 
00172     /* Make sure autochk was actually found */
00173     if (Flags & SMP_INVALID_PATH)
00174     {
00175         /* It wasn't, so create an error message to print on the screen */
00176         sprintf_nt(SourceString,
00177                    "%wZ program not found - skipping AUTOCHECK\n",
00178                    FileName);
00179         RtlInitAnsiString(&DestinationString, SourceString);
00180         if (RtlAnsiStringToUnicodeString(&Destination,
00181                                          &DestinationString,
00182                                          TRUE))
00183         {
00184             /* And show it */
00185             NtDisplayString(&Destination);
00186             RtlFreeUnicodeString(&Destination);
00187         }
00188     }
00189     else
00190     {
00191         /* Autochk is there, so record the BSD state */
00192         BootState = SmpSaveAndClearBootStatusData(&BootOkay, &ShutdownOkay);
00193 
00194         /* Build the path to autochk and place its arguments */
00195         RtlInitEmptyUnicodeString(&Destination, Buffer, sizeof(Buffer));
00196         RtlAppendUnicodeStringToString(&Destination, FileName);
00197         RtlAppendUnicodeToString(&Destination, L" ");
00198         RtlAppendUnicodeStringToString(&Destination, Arguments);
00199 
00200         /* Execute it */
00201         SmpExecuteImage(FileName,
00202                         Directory,
00203                         &Destination,
00204                         0,
00205                         Flags & ~SMP_AUTOCHK_FLAG,
00206                         NULL);
00207 
00208         /* Restore the BSD state */
00209         if (BootState) SmpRestoreBootStatusData(BootOkay, ShutdownOkay);
00210     }
00211 
00212     /* We're all done! */
00213     return STATUS_SUCCESS;
00214 }
00215 
00216 NTSTATUS
00217 NTAPI
00218 SmpExecuteCommand(IN PUNICODE_STRING CommandLine,
00219                   IN ULONG MuSessionId,
00220                   OUT PHANDLE ProcessId,
00221                   IN ULONG Flags)
00222 {
00223     NTSTATUS Status;
00224     UNICODE_STRING Arguments, Directory, FileName;
00225 
00226     /* There's no longer a debugging subsystem */
00227     if (Flags & SMP_DEBUG_FLAG) return STATUS_SUCCESS;
00228 
00229     /* Parse the command line to see what execution flags are requested */
00230     Status = SmpParseCommandLine(CommandLine,
00231                                  &Flags,
00232                                  &FileName,
00233                                  &Directory,
00234                                  &Arguments);
00235     if (!NT_SUCCESS(Status))
00236     {
00237         /* Fail if we couldn't do that */
00238         DPRINT1("SMSS: SmpParseCommand( %wZ ) failed - Status == %lx\n",
00239                 CommandLine, Status);
00240         return Status;
00241     }
00242 
00243     /* Check if autochk is requested */
00244     if (Flags & SMP_AUTOCHK_FLAG)
00245     {
00246         /* Run it */
00247         Status = SmpInvokeAutoChk(&FileName, &Directory, &Arguments, Flags);
00248     }
00249     else if (Flags & SMP_SUBSYSTEM_FLAG)
00250     {
00251         Status = SmpLoadSubSystem(&FileName,
00252                                   &Directory,
00253                                   CommandLine,
00254                                   MuSessionId,
00255                                   ProcessId,
00256                                   Flags);
00257     }
00258     else if (Flags & SMP_INVALID_PATH)
00259     {
00260         /* An invalid image was specified, fail */
00261         DPRINT1("SMSS: Image file (%wZ) not found\n", &FileName);
00262         Status = STATUS_OBJECT_NAME_NOT_FOUND;
00263     }
00264     else
00265     {
00266         /* An actual image name was present -- execute it */
00267         Status = SmpExecuteImage(&FileName,
00268                                  &Directory,
00269                                  CommandLine,
00270                                  MuSessionId,
00271                                  Flags,
00272                                  NULL);
00273     }
00274 
00275     /* Free all the token parameters */
00276     if (FileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FileName.Buffer);
00277     if (Directory.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Directory.Buffer);
00278     if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);
00279 
00280     /* Return to the caller */
00281     if (!NT_SUCCESS(Status))
00282     {
00283         DPRINT1("SMSS: Command '%wZ' failed - Status == %x\n",
00284                 CommandLine, Status);
00285     }
00286     return Status;
00287 }
00288 
00289 NTSTATUS
00290 NTAPI
00291 SmpExecuteInitialCommand(IN ULONG MuSessionId,
00292                          IN PUNICODE_STRING InitialCommand,
00293                          IN HANDLE InitialCommandProcess,
00294                          OUT PHANDLE ReturnPid)
00295 {
00296     NTSTATUS Status;
00297     RTL_USER_PROCESS_INFORMATION ProcessInfo;
00298     UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName;
00299     ULONG Flags = 0;
00300 
00301     /* Check if we haven't yet connected to ourselves */
00302     if (!SmApiPort)
00303     {
00304         /* Connect to ourselves, as a client */
00305         Status = SmConnectToSm(0, 0, 0, &SmApiPort);
00306         if (!NT_SUCCESS(Status))
00307         {
00308             DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status);
00309             return Status;
00310         }
00311     }
00312 
00313     /* Parse the initial command line */
00314     Status = SmpParseCommandLine(InitialCommand,
00315                                  (PULONG)&Flags,
00316                                  &ImageFileName,
00317                                  &ImageFileDirectory,
00318                                  &Arguments);
00319     if (Flags & SMP_INVALID_PATH)
00320     {
00321         /* Fail if it doesn't exist */
00322         DPRINT1("SMSS: Initial command image (%wZ) not found\n", &ImageFileName);
00323         if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
00324         return STATUS_OBJECT_NAME_NOT_FOUND;
00325     }
00326 
00327     /* And fail if any other reason is also true */
00328     if (!NT_SUCCESS(Status))
00329     {
00330         DPRINT1("SMSS: SmpParseCommand( %wZ ) failed - Status == %lx\n",
00331                 InitialCommand, Status);
00332         return Status;
00333     }
00334 
00335     /* Execute the initial command -- but defer its full execution */
00336     Status = SmpExecuteImage(&ImageFileName,
00337                              &ImageFileDirectory,
00338                              InitialCommand,
00339                              MuSessionId,
00340                              SMP_DEFERRED_FLAG,
00341                              &ProcessInfo);
00342 
00343     /* Free any buffers we had lying around */
00344     if (ImageFileName.Buffer)
00345     {
00346         RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
00347     }
00348     if (ImageFileDirectory.Buffer)
00349     {
00350         RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer);
00351     }
00352     if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);
00353 
00354     /* Bail out if we couldn't execute the initial command */
00355     if (!NT_SUCCESS(Status)) return Status;
00356 
00357     /* Now duplicate the handle to this process */
00358     Status = NtDuplicateObject(NtCurrentProcess(),
00359                                ProcessInfo.ProcessHandle,
00360                                NtCurrentProcess(),
00361                                InitialCommandProcess,
00362                                PROCESS_ALL_ACCESS,
00363                                0,
00364                                0);
00365     if (!NT_SUCCESS(Status))
00366     {
00367         /* Kill it utterly if duplication failed */
00368         DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status);
00369         NtTerminateProcess(ProcessInfo.ProcessHandle, Status);
00370         NtResumeThread(ProcessInfo.ThreadHandle, NULL);
00371         NtClose(ProcessInfo.ThreadHandle);
00372         NtClose(ProcessInfo.ProcessHandle);
00373         return Status;
00374     }
00375 
00376     /* Return PID to the caller, and set this as the initial command PID */
00377     if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess;
00378     if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess;
00379 
00380     /* Now call our server execution function to wrap up its initialization */
00381     Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE);
00382     if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status);
00383     return Status;
00384 }
00385 
00386 NTSTATUS
00387 NTAPI
00388 SmpTerminate(IN PULONG_PTR Parameters,
00389              IN ULONG ParameterMask,
00390              IN ULONG ParameterCount)
00391 {
00392     NTSTATUS Status;
00393     BOOLEAN Old;
00394     ULONG Response;
00395 
00396     /* Give the shutdown privilege to the thread */
00397     if (RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, TRUE, &Old) ==
00398         STATUS_NO_TOKEN)
00399     {
00400         /* Thread doesn't have a token, give it to the entire process */
00401         RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old);
00402     }
00403 
00404     /* Take down the process/machine with a hard error */
00405     Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
00406                               ParameterCount,
00407                               ParameterMask,
00408                               Parameters,
00409                               OptionShutdownSystem,
00410                               &Response);
00411 
00412     /* Terminate the process if the hard error didn't already */
00413     return NtTerminateProcess(NtCurrentProcess(), Status);
00414 }
00415 
00416 LONG
00417 SmpUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
00418 {
00419     ULONG_PTR Parameters[4];
00420     UNICODE_STRING DestinationString;
00421 
00422     /* Print and breakpoint into the debugger */
00423     DbgPrint("SMSS: Unhandled exception - Status == %x  IP == %x\n",
00424              ExceptionInfo->ExceptionRecord->ExceptionCode,
00425              ExceptionInfo->ExceptionRecord->ExceptionAddress);
00426     DbgPrint("      Memory Address: %x  Read/Write: %x\n",
00427              ExceptionInfo->ExceptionRecord->ExceptionInformation[0],
00428              ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
00429     DbgBreakPoint();
00430 
00431     /* Build the hard error and terminate */
00432     RtlInitUnicodeString(&DestinationString, L"Unhandled Exception in Session Manager");
00433     Parameters[0] = (ULONG_PTR)&DestinationString;
00434     Parameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode;
00435     Parameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
00436     Parameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord;
00437     SmpTerminate(Parameters, 1, RTL_NUMBER_OF(Parameters));
00438 
00439     /* We hould never get here */
00440     ASSERT(FALSE);
00441     return EXCEPTION_EXECUTE_HANDLER;
00442 }
00443 
00444 NTSTATUS
00445 _main(IN INT argc,
00446       IN PCHAR argv[],
00447       IN PCHAR envp[],
00448       IN ULONG DebugFlag)
00449 {
00450     NTSTATUS Status;
00451     KPRIORITY SetBasePriority;
00452     ULONG_PTR Parameters[4];
00453     HANDLE Handles[2];
00454     PVOID State;
00455     ULONG Flags;
00456     PROCESS_BASIC_INFORMATION ProcessInfo;
00457     UNICODE_STRING DbgString, InitialCommand;
00458 
00459     /* Make us critical */
00460     RtlSetProcessIsCritical(TRUE, NULL, FALSE);
00461     RtlSetThreadIsCritical(TRUE, NULL, FALSE);
00462 
00463     /* Raise our priority */
00464     SetBasePriority = 11;
00465     Status = NtSetInformationProcess(NtCurrentProcess(),
00466                                      ProcessBasePriority,
00467                                      (PVOID)&SetBasePriority,
00468                                      sizeof(SetBasePriority));
00469     ASSERT(NT_SUCCESS(Status));
00470 
00471     /* Save the debug flag if it was passed */
00472     if (DebugFlag) SmpDebug = DebugFlag;
00473 
00474     /* Build the hard error parameters */
00475     Parameters[0] = (ULONG_PTR)&DbgString;
00476     Parameters[1] = Parameters[2] = Parameters[3] = 0;
00477 
00478     /* Enter SEH so we can terminate correctly if anything goes wrong */
00479     _SEH2_TRY
00480     {
00481         /* Initialize SMSS */
00482         Status = SmpInit(&InitialCommand, Handles);
00483         if (!NT_SUCCESS(Status))
00484         {
00485             DPRINT1("SMSS: SmpInit return failure - Status == %x\n", Status);
00486             RtlInitUnicodeString(&DbgString, L"Session Manager Initialization");
00487             Parameters[1] = Status;
00488             _SEH2_LEAVE;
00489         }
00490 
00491         /* Get the global flags */
00492         Status = NtQuerySystemInformation(SystemFlagsInformation,
00493                                           &Flags,
00494                                           sizeof(Flags),
00495                                           NULL);
00496         ASSERT(NT_SUCCESS(Status));
00497 
00498         /* Before executing the initial command check if the debug flag is on */
00499         if (Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX))
00500         {
00501             /* SMSS should launch ntsd with a few parameters at this point */
00502             DPRINT1("Global Flags Set to SMSS Debugging: Not yet supported\n");
00503         }
00504 
00505         /* Execute the initial command (Winlogon.exe) */
00506         Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], NULL);
00507         if (!NT_SUCCESS(Status))
00508         {
00509             /* Fail and raise a hard error */
00510             DPRINT1("SMSS: Execute Initial Command failed\n");
00511             RtlInitUnicodeString(&DbgString,
00512                                  L"Session Manager ExecuteInitialCommand");
00513             Parameters[1] = Status;
00514             _SEH2_LEAVE;
00515         }
00516 
00517         /*  Check if we're already attached to a session */
00518         Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State);
00519         if (AttachedSessionId != -1)
00520         {
00521             /* Detach from it, we should be in no session right now */
00522             Status = NtSetSystemInformation(SystemSessionDetach,
00523                                             &AttachedSessionId,
00524                                             sizeof(AttachedSessionId));
00525             ASSERT(NT_SUCCESS(Status));
00526             AttachedSessionId = -1;
00527         }
00528         SmpReleasePrivilege(State);
00529 
00530         /* Wait on either CSRSS or Winlogon to die */
00531         Status = NtWaitForMultipleObjects(RTL_NUMBER_OF(Handles),
00532                                           Handles,
00533                                           WaitAny,
00534                                           FALSE,
00535                                           NULL);
00536         if (Status == STATUS_WAIT_0)
00537         {
00538             /* CSRSS is dead, get exit code and prepare for the hard error */
00539             RtlInitUnicodeString(&DbgString, L"Windows SubSystem");
00540             Status = NtQueryInformationProcess(Handles[0],
00541                                                ProcessBasicInformation,
00542                                                &ProcessInfo,
00543                                                sizeof(ProcessInfo),
00544                                                NULL);
00545             DPRINT1("SMSS: Windows subsystem terminated when it wasn't supposed to.\n");
00546         }
00547         else
00548         {
00549             /* The initial command is dead or we have another failure */
00550             RtlInitUnicodeString(&DbgString, L"Windows Logon Process");
00551             if (Status == STATUS_WAIT_1)
00552             {
00553                 /* Winlogon.exe got terminated, get its exit code */
00554                 Status = NtQueryInformationProcess(Handles[1],
00555                                                    ProcessBasicInformation,
00556                                                    &ProcessInfo,
00557                                                    sizeof(ProcessInfo),
00558                                                    NULL);
00559             }
00560             else
00561             {
00562                 /* Something else satisfied our wait, so set the wait status */
00563                 ProcessInfo.ExitStatus = Status;
00564                 Status = STATUS_SUCCESS;
00565             }
00566             DPRINT1("SMSS: Initial command '%wZ' terminated when it wasn't supposed to.\n",
00567                     &InitialCommand);
00568         }
00569 
00570         /* Check if NtQueryInformationProcess was successful */
00571         if (NT_SUCCESS(Status))
00572         {
00573             /* Then we must have a valid exit status in the structure, use it */
00574             Parameters[1] = ProcessInfo.ExitStatus;
00575         }
00576         else
00577         {
00578             /* We really don't know what happened, so set a generic error */
00579             Parameters[1] = STATUS_UNSUCCESSFUL;
00580         }
00581     }
00582     _SEH2_EXCEPT(SmpUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
00583     {
00584         /* The filter should never return here */
00585         ASSERT(FALSE);
00586     }
00587     _SEH2_END;
00588 
00589     /* Something in the init loop failed, terminate SMSS */
00590     return SmpTerminate(Parameters, 1, RTL_NUMBER_OF(Parameters));
00591 }
00592 
00593 /* EOF */

Generated on Sat May 26 2012 04:17:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.