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

harderr.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/ex/harderr.c
00005  * PURPOSE:         Error Functions and Status/Exception Dispatching/Raising
00006  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 #define TAG_ERR ' rrE'
00016 
00017 /* GLOBALS ****************************************************************/
00018 
00019 BOOLEAN ExReadyForErrors = FALSE;
00020 PVOID ExpDefaultErrorPort = NULL;
00021 PEPROCESS ExpDefaultErrorPortProcess = NULL;
00022 
00023 /* FUNCTIONS ****************************************************************/
00024 
00025 /*++
00026 * @name ExpSystemErrorHandler
00027 *
00028 * For now it's a stub
00029 *
00030 * @param ErrorStatus
00031 *        FILLME
00032 *
00033 * @param NumberOfParameters
00034 *        FILLME
00035 *
00036 * @param UnicodeStringParameterMask
00037 *        FILLME
00038 *
00039 * @param Parameters
00040 *        FILLME
00041 *
00042 * @param ValidResponseOptions
00043 *        FILLME
00044 *
00045 * @param Response
00046 *        FILLME
00047 *
00048 * @return None
00049 *
00050 * @remarks None
00051 *
00052 *--*/
00053 NTSTATUS
00054 NTAPI
00055 ExpSystemErrorHandler(IN NTSTATUS ErrorStatus,
00056                       IN ULONG NumberOfParameters,
00057                       IN ULONG UnicodeStringParameterMask,
00058                       IN PULONG_PTR Parameters,
00059                       IN BOOLEAN Shutdown)
00060 {
00061     ULONG_PTR BugCheckParameters[MAXIMUM_HARDERROR_PARAMETERS] = {0, 0, 0, 0};
00062     ULONG i;
00063 
00064     /* Sanity check */
00065     ASSERT(NumberOfParameters <= MAXIMUM_HARDERROR_PARAMETERS);
00066 
00067     /*
00068      * KeBugCheck expects MAXIMUM_HARDERROR_PARAMETERS parameters,
00069      * but we might get called with less, so use a local buffer here.
00070      */
00071     for (i = 0; i < NumberOfParameters; i++)
00072     {
00073         /* Copy them over */
00074         BugCheckParameters[i] = Parameters[i];
00075     }
00076 
00077     /* FIXME: STUB */
00078     KeBugCheckEx(FATAL_UNHANDLED_HARD_ERROR,
00079                  ErrorStatus,
00080                  (ULONG_PTR)BugCheckParameters,
00081                  0,
00082                  0);
00083     return STATUS_SUCCESS;
00084 }
00085 
00086 /*++
00087  * @name ExpRaiseHardError
00088  *
00089  * For now it's a stub
00090  *
00091  * @param ErrorStatus
00092  *        FILLME
00093  *
00094  * @param NumberOfParameters
00095  *        FILLME
00096  *
00097  * @param UnicodeStringParameterMask
00098  *        FILLME
00099  *
00100  * @param Parameters
00101  *        FILLME
00102  *
00103  * @param ValidResponseOptions
00104  *        FILLME
00105  *
00106  * @param Response
00107  *        FILLME
00108  *
00109  * @return None
00110  *
00111  * @remarks None
00112  *
00113  *--*/
00114 NTSTATUS
00115 NTAPI
00116 ExpRaiseHardError(IN NTSTATUS ErrorStatus,
00117                   IN ULONG NumberOfParameters,
00118                   IN ULONG UnicodeStringParameterMask,
00119                   IN PULONG_PTR Parameters,
00120                   IN ULONG ValidResponseOptions,
00121                   OUT PULONG Response)
00122 {
00123     PEPROCESS Process = PsGetCurrentProcess();
00124     PETHREAD Thread = PsGetCurrentThread();
00125     UCHAR Buffer[PORT_MAXIMUM_MESSAGE_LENGTH];
00126     PHARDERROR_MSG Message = (PHARDERROR_MSG)Buffer;
00127     NTSTATUS Status;
00128     HANDLE PortHandle;
00129     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
00130     PAGED_CODE();
00131 
00132     /* Check if this error will shutdown the system */
00133     if (ValidResponseOptions == OptionShutdownSystem)
00134     {
00135         /* Check for privilege */
00136         if (!SeSinglePrivilegeCheck(SeShutdownPrivilege, PreviousMode))
00137         {
00138             /* No rights */
00139             *Response = ResponseNotHandled;
00140             return STATUS_PRIVILEGE_NOT_HELD;
00141         }
00142 
00143         /* Don't handle any new hard errors */
00144         ExReadyForErrors = FALSE;
00145     }
00146 
00147     /* Check if hard errors are not disabled */
00148     if (!Thread->HardErrorsAreDisabled)
00149     {
00150         /* Check if we can't do errors anymore, and this is serious */
00151         if ((!ExReadyForErrors) && (NT_ERROR(ErrorStatus)))
00152         {
00153             /* Use the system handler */
00154             ExpSystemErrorHandler(ErrorStatus,
00155                                   NumberOfParameters,
00156                                   UnicodeStringParameterMask,
00157                                   Parameters,
00158                                   (PreviousMode != KernelMode) ? TRUE: FALSE);
00159         }
00160     }
00161 
00162     /* Enable hard error processing if it is enabled for the process
00163      * or if the exception status forces it */
00164     if ((Process->DefaultHardErrorProcessing & 1) ||
00165         (ErrorStatus & 0x10000000))
00166     {
00167         /* Check if we have an exception port */
00168         if (Process->ExceptionPort)
00169         {
00170             /* Use the port */
00171             PortHandle = Process->ExceptionPort;
00172         }
00173         else
00174         {
00175             /* Use our default system port */
00176             PortHandle = ExpDefaultErrorPort;
00177         }
00178     }
00179     else
00180     {
00181         /* Don't process the error */
00182         PortHandle = NULL;
00183     }
00184 
00185     /* If hard errors are disabled, do nothing */
00186     if (Thread->HardErrorsAreDisabled) PortHandle = NULL;
00187 
00188     /* Now check if we have a port */
00189     if (PortHandle)
00190     {
00191         /* Check if this is the default process */
00192         if (Process == ExpDefaultErrorPortProcess)
00193         {
00194             /* We can't handle the error, check if this is critical */
00195             if (NT_ERROR(ErrorStatus))
00196             {
00197                 /* It is, invoke the system handler */
00198                 ExpSystemErrorHandler(ErrorStatus,
00199                                       NumberOfParameters,
00200                                       UnicodeStringParameterMask,
00201                                       Parameters,
00202                                       (PreviousMode != KernelMode) ? TRUE: FALSE);
00203 
00204                 /* If we survived, return to caller */
00205                 *Response = ResponseReturnToCaller;
00206                 return STATUS_SUCCESS;
00207             }
00208         }
00209 
00210         /* Setup the LPC Message */
00211         Message->h.u1.Length = (sizeof(HARDERROR_MSG) << 16) |
00212                                (sizeof(HARDERROR_MSG) - sizeof(PORT_MESSAGE));
00213         Message->h.u2.ZeroInit = 0;
00214         Message->h.u2.s2.Type = LPC_ERROR_EVENT;
00215         Message->Status = ErrorStatus &~ 0x10000000;
00216         Message->ValidResponseOptions = ValidResponseOptions;
00217         Message->UnicodeStringParameterMask = UnicodeStringParameterMask;
00218         Message->NumberOfParameters = NumberOfParameters;
00219         KeQuerySystemTime(&Message->ErrorTime);
00220 
00221         /* Copy the parameters */
00222         if (Parameters) RtlMoveMemory(&Message->Parameters,
00223                                       Parameters,
00224                                       sizeof(ULONG_PTR) * NumberOfParameters);
00225 
00226         /* Send the LPC Message */
00227         Status = LpcRequestWaitReplyPort(PortHandle,
00228                                          (PVOID)Message,
00229                                          (PVOID)Message);
00230         if (NT_SUCCESS(Status))
00231         {
00232             /* Check what kind of response we got */
00233             if ((Message->Response != ResponseReturnToCaller) &&
00234                 (Message->Response != ResponseNotHandled) &&
00235                 (Message->Response != ResponseAbort) &&
00236                 (Message->Response != ResponseCancel) &&
00237                 (Message->Response != ResponseIgnore) &&
00238                 (Message->Response != ResponseNo) &&
00239                 (Message->Response != ResponseOk) &&
00240                 (Message->Response != ResponseRetry) &&
00241                 (Message->Response != ResponseYes) &&
00242                 (Message->Response != ResponseTryAgain) &&
00243                 (Message->Response != ResponseContinue))
00244             {
00245                 /* Reset to a default one */
00246                 Message->Response = ResponseReturnToCaller;
00247             }
00248 
00249             /* Set the response */
00250             *Response = Message->Response;
00251         }
00252         else
00253         {
00254             /* Set the response */
00255             *Response = ResponseReturnToCaller;
00256         }
00257     }
00258     else
00259     {
00260         /* Set defaults */
00261         *Response = ResponseReturnToCaller;
00262         Status = STATUS_SUCCESS;
00263     }
00264 
00265     /* Return status */
00266     return Status;
00267 }
00268 
00269 /*++
00270  * @name ExRaiseAccessViolation
00271  * @implemented
00272  *
00273  * The ExRaiseAccessViolation routine can be used with structured exception
00274  * handling to throw a driver-determined exception for a memory access
00275  * violation that occurs when a driver processes I/O requests.
00276  * See: http://msdn.microsoft.com/library/en-us/Kernel_r/hh/Kernel_r/k102_71b4c053-599c-4a6d-8a59-08aae6bdc534.xml.asp?frame=true
00277  *      http://www.osronline.com/ddkx/kmarch/k102_814i.htm
00278  *
00279  * @return None
00280  *
00281  * @remarks None
00282  *
00283  *--*/
00284 VOID
00285 NTAPI
00286 ExRaiseAccessViolation(VOID)
00287 {
00288     /* Raise the Right Status */
00289     RtlRaiseStatus(STATUS_ACCESS_VIOLATION);
00290 }
00291 
00292 /*++
00293  * @name ExRaiseDatatypeMisalignment
00294  * @implemented
00295  *
00296  * ExRaiseDatatypeMisalignment raises an exception with the exception
00297  * code set to STATUS_DATATYPE_MISALIGNMENT
00298  * See: MSDN / DDK
00299  *      http://www.osronline.com/ddkx/kmarch/k102_814i.htm
00300  *
00301  * @return None
00302  *
00303  * @remarks None
00304  *
00305  *--*/
00306 VOID
00307 NTAPI
00308 ExRaiseDatatypeMisalignment(VOID)
00309 {
00310     /* Raise the Right Status */
00311     RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
00312 }
00313 
00314 /*++
00315  * @name ExSystemExceptionFilter
00316  * @implemented
00317  *
00318  * TODO: Add description
00319  *
00320  * @return FILLME
00321  *
00322  * @remarks None
00323  *
00324  *--*/
00325 LONG
00326 NTAPI
00327 ExSystemExceptionFilter(VOID)
00328 {
00329     return KeGetPreviousMode() != KernelMode ?
00330            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
00331 }
00332 
00333 /*++
00334  * @name ExRaiseHardError
00335  * @implemented
00336  *
00337  * See NtRaiseHardError
00338  *
00339  * @param ErrorStatus
00340  *        Error Code
00341  *
00342  * @param NumberOfParameters
00343  *        Number of optional parameters in Parameters array
00344  *
00345  * @param UnicodeStringParameterMask
00346  *        Optional string parameter (can be only one per error code)
00347  *
00348  * @param Parameters
00349  *        Array of ULONG parameters for use in error message string
00350  *
00351  * @param ValidResponseOptions
00352  *        See HARDERROR_RESPONSE_OPTION for possible values description
00353  *
00354  * @param Response
00355  *        Pointer to HARDERROR_RESPONSE enumeration
00356  *
00357  * @return None
00358  *
00359  * @remarks None
00360  *
00361  *--*/
00362 NTSTATUS
00363 NTAPI
00364 ExRaiseHardError(IN NTSTATUS ErrorStatus,
00365                  IN ULONG NumberOfParameters,
00366                  IN ULONG UnicodeStringParameterMask,
00367                  IN PULONG_PTR Parameters,
00368                  IN ULONG ValidResponseOptions,
00369                  OUT PULONG Response)
00370 {
00371     SIZE_T Size;
00372     UNICODE_STRING CapturedParams[MAXIMUM_HARDERROR_PARAMETERS];
00373     ULONG i;
00374     PVOID UserData = NULL;
00375     PHARDERROR_USER_PARAMETERS UserParams;
00376     PWSTR BufferBase;
00377     ULONG SafeResponse;
00378     NTSTATUS Status;
00379     PAGED_CODE();
00380 
00381     /* Check if we have parameters */
00382     if (Parameters)
00383     {
00384         /* Check if we have strings */
00385         if (UnicodeStringParameterMask)
00386         {
00387             /* Calculate the required size */
00388             Size = FIELD_OFFSET(HARDERROR_USER_PARAMETERS, Buffer[0]);
00389 
00390             /* Loop each parameter */
00391             for (i = 0; i < NumberOfParameters; i++)
00392             {
00393                 /* Check if it's part of the mask */
00394                 if (UnicodeStringParameterMask & (1 << i))
00395                 {
00396                     /* Copy it */
00397                     RtlMoveMemory(&CapturedParams[i],
00398                                   (PVOID)Parameters[i],
00399                                   sizeof(UNICODE_STRING));
00400 
00401                     /* Increase the size */
00402                     Size += CapturedParams[i].MaximumLength;
00403                 }
00404             }
00405 
00406             /* Allocate the user data region */
00407             Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
00408                                              &UserData,
00409                                              0,
00410                                              &Size,
00411                                              MEM_COMMIT,
00412                                              PAGE_READWRITE);
00413             if (!NT_SUCCESS(Status)) return Status;
00414 
00415             /* Set the pointers to our data */
00416             UserParams = UserData;
00417             BufferBase = UserParams->Buffer;
00418 
00419             /* Loop parameters again */
00420             for (i = 0; i < NumberOfParameters; i++)
00421             {
00422                 /* Check if we're in the mask */
00423                 if (UnicodeStringParameterMask & (1 << i))
00424                 {
00425                     /* Update the base */
00426                     UserParams->Parameters[i] = (ULONG_PTR)&UserParams->Strings[i];
00427 
00428                     /* Copy the string buffer */
00429                     RtlMoveMemory(BufferBase,
00430                                   CapturedParams[i].Buffer,
00431                                   CapturedParams[i].MaximumLength);
00432 
00433                     /* Set buffer */
00434                     CapturedParams[i].Buffer = BufferBase;
00435 
00436                     /* Copy the string structure */
00437                     UserParams->Strings[i] = CapturedParams[i];
00438 
00439                     /* Update the pointer */
00440                     BufferBase += CapturedParams[i].MaximumLength;
00441                 }
00442                 else
00443                 {
00444                     /* No need to copy any strings */
00445                     UserParams->Parameters[i] = Parameters[i];
00446                 }
00447             }
00448         }
00449         else
00450         {
00451             /* Just keep the data as is */
00452             UserData = Parameters;
00453         }
00454     }
00455 
00456     /* Now call the worker function */
00457     Status = ExpRaiseHardError(ErrorStatus,
00458                                NumberOfParameters,
00459                                UnicodeStringParameterMask,
00460                                UserData,
00461                                ValidResponseOptions,
00462                                &SafeResponse);
00463 
00464     /* Check if we had done user-mode allocation */
00465     if ((UserData) && (UserData != Parameters))
00466     {
00467         /* We did! Delete it */
00468         Size = 0;
00469         ZwFreeVirtualMemory(NtCurrentProcess(),
00470                             &UserData,
00471                             &Size,
00472                             MEM_RELEASE);
00473     }
00474 
00475     /* Return status and the response */
00476     *Response = SafeResponse;
00477     return Status;
00478 }
00479 
00480 /*++
00481  * @name NtRaiseHardError
00482  * @implemented
00483  *
00484  * This function sends HARDERROR_MSG LPC message to listener
00485  * (typically CSRSS.EXE). See NtSetDefaultHardErrorPort for more information
00486  * See: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Error/NtRaiseHardError.html
00487  *
00488  * @param ErrorStatus
00489  *        Error Code
00490  *
00491  * @param NumberOfParameters
00492  *        Number of optional parameters in Parameters array
00493  *
00494  * @param UnicodeStringParameterMask
00495  *        Optional string parameter (can be only one per error code)
00496  *
00497  * @param Parameters
00498  *        Array of ULONG_PTR parameters for use in error message string
00499  *
00500  * @param ValidResponseOptions
00501  *        See HARDERROR_RESPONSE_OPTION for possible values description
00502  *
00503  * @param Response
00504  *        Pointer to HARDERROR_RESPONSE enumeration
00505  *
00506  * @return Status
00507  *
00508  * @remarks NtRaiseHardError is easy way to display message in GUI
00509  *          without loading Win32 API libraries
00510  *
00511  *--*/
00512 NTSTATUS
00513 NTAPI
00514 NtRaiseHardError(IN NTSTATUS ErrorStatus,
00515                  IN ULONG NumberOfParameters,
00516                  IN ULONG UnicodeStringParameterMask,
00517                  IN PULONG_PTR Parameters,
00518                  IN ULONG ValidResponseOptions,
00519                  OUT PULONG Response)
00520 {
00521     NTSTATUS Status = STATUS_SUCCESS;
00522     PULONG_PTR SafeParams = NULL;
00523     ULONG SafeResponse;
00524     UNICODE_STRING SafeString;
00525     ULONG i;
00526     ULONG ParamSize;
00527     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00528 
00529     /* Validate parameter count */
00530     if (NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS)
00531     {
00532         /* Fail */
00533         return STATUS_INVALID_PARAMETER_2;
00534     }
00535 
00536     /* Make sure we have some at least */
00537     if ((Parameters) && !(NumberOfParameters))
00538     {
00539         /* Fail */
00540         return STATUS_INVALID_PARAMETER_2;
00541     }
00542 
00543     /* Check if we were called from user-mode */
00544     if (PreviousMode != KernelMode)
00545     {
00546         /* First validate the responses */
00547         switch (ValidResponseOptions)
00548         {
00549             /* Check all valid cases */
00550             case OptionAbortRetryIgnore:
00551             case OptionOk:
00552             case OptionOkCancel:
00553             case OptionRetryCancel:
00554             case OptionYesNo:
00555             case OptionYesNoCancel:
00556             case OptionShutdownSystem:
00557                 break;
00558 
00559             /* Anything else is invalid */
00560             default:
00561                 return STATUS_INVALID_PARAMETER_4;
00562         }
00563 
00564         /* Enter SEH Block */
00565         _SEH2_TRY
00566         {
00567             /* Validate the response pointer */
00568             ProbeForWriteUlong(Response);
00569 
00570             /* Check if we have parameters */
00571             if (Parameters)
00572             {
00573                 /* Validate the parameter pointers */
00574                 ParamSize = sizeof(ULONG_PTR) * NumberOfParameters;
00575                 ProbeForRead(Parameters, ParamSize, sizeof(ULONG_PTR));
00576 
00577                 /* Allocate a safe buffer */
00578                 SafeParams = ExAllocatePoolWithTag(PagedPool,
00579                                                    ParamSize,
00580                                                    TAG_ERR);
00581 
00582                 /* Copy them */
00583                 RtlCopyMemory(SafeParams, Parameters, ParamSize);
00584 
00585                 /* Now check if there's strings in it */
00586                 if (UnicodeStringParameterMask)
00587                 {
00588                     /* Loop every string */
00589                     for (i = 0; i < NumberOfParameters; i++)
00590                     {
00591                         /* Check if this parameter is a string */
00592                         if (UnicodeStringParameterMask & (1 << i))
00593                         {
00594                             /* Probe the structure */
00595                             ProbeForRead((PVOID)SafeParams[i],
00596                                          sizeof(UNICODE_STRING),
00597                                          sizeof(ULONG_PTR));
00598 
00599                             /* Capture it */
00600                             RtlCopyMemory(&SafeString,
00601                                           (PVOID)SafeParams[i],
00602                                           sizeof(UNICODE_STRING));
00603 
00604                             /* Probe the buffer */
00605                             ProbeForRead(SafeString.Buffer,
00606                                          SafeString.MaximumLength,
00607                                          sizeof(UCHAR));
00608                         }
00609                     }
00610                 }
00611             }
00612         }
00613         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00614         {
00615             /* Free captured buffer */
00616             if (SafeParams) ExFreePoolWithTag(SafeParams, TAG_ERR);
00617 
00618             /* Return the exception code */
00619             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00620         }
00621         _SEH2_END;
00622 
00623         /* Call the system function directly, because we probed */
00624         ExpRaiseHardError(ErrorStatus,
00625                           NumberOfParameters,
00626                           UnicodeStringParameterMask,
00627                           SafeParams,
00628                           ValidResponseOptions,
00629                           &SafeResponse);
00630     }
00631     else
00632     {
00633         /* Reuse variable */
00634         SafeParams = Parameters;
00635 
00636         /*
00637          * Call the Executive Function. It will probe and copy pointers to
00638          * user-mode
00639          */
00640         ExRaiseHardError(ErrorStatus,
00641                          NumberOfParameters,
00642                          UnicodeStringParameterMask,
00643                          SafeParams,
00644                          ValidResponseOptions,
00645                          &SafeResponse);
00646     }
00647 
00648     /* Check if we were called in user-mode */
00649     if (PreviousMode != KernelMode)
00650     {
00651         /* That means we have a buffer to free */
00652         if (SafeParams) ExFreePoolWithTag(SafeParams, TAG_ERR);
00653 
00654         /* Enter SEH Block for return */
00655         _SEH2_TRY
00656         {
00657             /* Return the response */
00658             *Response = SafeResponse;
00659         }
00660         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00661         {
00662             /* Get the exception code */
00663             Status = _SEH2_GetExceptionCode();
00664         }
00665         _SEH2_END;
00666     }
00667     else
00668     {
00669         /* Return the response */
00670         *Response = SafeResponse;
00671     }
00672 
00673     /* Return status */
00674     return Status;
00675 }
00676 
00677 /*++
00678  * @name NtSetDefaultHardErrorPort
00679  * @implemented
00680  *
00681  * NtSetDefaultHardErrorPort is typically called only once. After call,
00682  * kernel set BOOLEAN flag named _ExReadyForErrors to TRUE, and all other
00683  * tries to change default port are broken with STATUS_UNSUCCESSFUL error code
00684  * See: http://www.windowsitlibrary.com/Content/356/08/2.html
00685  *      http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Error/NtSetDefaultHardErrorPort.html
00686  *
00687  * @param PortHandle
00688  *        Handle to named port object
00689  *
00690  * @return Status
00691  *
00692  * @remarks Privileges: SE_TCB_PRIVILEGE
00693  *
00694  *--*/
00695 NTSTATUS
00696 NTAPI
00697 NtSetDefaultHardErrorPort(IN HANDLE PortHandle)
00698 {
00699     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00700     NTSTATUS Status = STATUS_UNSUCCESSFUL;
00701 
00702     /* Check if we have the Privilege */
00703     if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
00704     {
00705         DPRINT1("NtSetDefaultHardErrorPort: Caller requires "
00706                 "the SeTcbPrivilege privilege!\n");
00707         return STATUS_PRIVILEGE_NOT_HELD;
00708     }
00709 
00710     /* Only called once during bootup, make sure we weren't called yet */
00711     if (!ExReadyForErrors)
00712     {
00713         /* Reference the port */
00714         Status = ObReferenceObjectByHandle(PortHandle,
00715                                            0,
00716                                            LpcPortObjectType,
00717                                            PreviousMode,
00718                                            (PVOID*)&ExpDefaultErrorPort,
00719                                            NULL);
00720         if (NT_SUCCESS(Status))
00721         {
00722             /* Save the data */
00723             ExpDefaultErrorPortProcess = PsGetCurrentProcess();
00724             ExReadyForErrors = TRUE;
00725         }
00726     }
00727 
00728     /* Return status to caller */
00729     return Status;
00730 }
00731 
00732 VOID
00733 __cdecl
00734 _purecall(VOID)
00735 {
00736     /* Not supported in Kernel Mode */
00737     RtlRaiseStatus(STATUS_NOT_IMPLEMENTED);
00738 }
00739 
00740 /* EOF */

Generated on Mon May 28 2012 04:36:59 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.