test: ex/harderr.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# harderr.c File Reference

`#include "exp.h"`

Go to the source code of this file.

## Defines

#define | HARDERROR_MSG_OVERHEAD (sizeof(HARDERROR_MSG) - sizeof(PORT_MESSAGE))
#define | HARDERROR_API_MSG_LENGTH sizeof(HARDERROR_MSG)<<16 | (HARDERROR_MSG_OVERHEAD)

## Functions

NTSTATUS | ExpRaiseHardError (IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
VOID | ExpSystemErrorHandler (IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN BOOLEAN CallShutdown)
NTSTATUS | NtRaiseHardError (IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
NTSTATUS | ExRaiseHardError (IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
NTSTATUS | NtSetDefaultHardErrorPort (IN HANDLE DefaultHardErrorPort)
VOID __cdecl | _purecall ()

## Variables

ULONG | KiBugCheckData [5]
ULONG | KeBugCheckCount
PEPROCESS | ExpDefaultErrorPortProcess
BOOLEAN | ExReadyForErrors = FALSE
BOOLEAN | ExpTooLateForErrors = FALSE
HANDLE | ExpDefaultErrorPort
PVOID | PsSystemDllDllBase

## Define Documentation

#define HARDERROR_API_MSG_LENGTH sizeof(HARDERROR_MSG)<<16 | (HARDERROR_MSG_OVERHEAD)

| Definition at line 54 of file ex/harderr.c. Referenced by ExpRaiseHardError().

#define HARDERROR_MSG_OVERHEAD (sizeof(HARDERROR_MSG) - sizeof(PORT_MESSAGE))

| Definition at line 53 of file ex/harderr.c.

## Function Documentation

VOID __cdecl _purecall | ( |  | ) |

Definition at line 926 of file ex/harderr.c.

References ASSERTMSG, ExRaiseStatus(), and FALSE.

    00927 {
    00928     ASSERTMSG("_purecall() was called", FALSE);
    00929     ExRaiseStatus(STATUS_NOT_IMPLEMENTED);
    00930 }

NTSTATUS ExpRaiseHardError | ( | IN NTSTATUS | ErrorStatus,
|  | IN ULONG | NumberOfParameters,
|  | IN ULONG | UnicodeStringParameterMask,
|  | IN PULONG_PTR | Parameters,
|  | IN ULONG | ValidResponseOptions,
|  | OUT PULONG | Response
| ) |

Definition at line 349 of file ex/harderr.c.

References _EPROCESS::DefaultHardErrorProcessing, EXCEPTION_EXECUTE_HANDLER, _EPROCESS::ExceptionPort, ExpDefaultErrorPort, ExpDefaultErrorPortProcess, ExpSystemErrorHandler(), ExReadyForErrors, FALSE, HARDERROR_API_MSG_LENGTH, IS_SYSTEM_THREAD, KeQuerySystemTime(), KernelMode, KPROCESSOR_MODE, LpcRequestWaitReplyPort(), NT_ERROR, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PsGetCurrentProcess, PsGetCurrentThread, SeShutdownPrivilege, SeSinglePrivilegeCheck(), Status, and TRUE.

Referenced by ExRaiseHardError(), and NtRaiseHardError().

    00357 {
    00358
    00359     PEPROCESS Process;
    00360     ULONG_PTR MessageBuffer[PORT_MAXIMUM_MESSAGE_LENGTH/sizeof(ULONG_PTR)];
    00361     PHARDERROR_MSG m;
    00362     NTSTATUS Status;
    00363     HANDLE ErrorPort;
    00364     KPROCESSOR_MODE PreviousMode;
    00365
    00366     PAGED_CODE();
    00367
    00368     m = (PHARDERROR_MSG)&MessageBuffer[0];
    00369     PreviousMode = KeGetPreviousMode();
    00370
    00371     if (ValidResponseOptions == OptionShutdownSystem) {
    00372         //
    00373         // Check to see if the caller has the privilege to make this
    00374         // call.
    00375         //
    00376
    00377
    00378         if (!SeSinglePrivilegeCheck( SeShutdownPrivilege, PreviousMode )) {
    00379             return STATUS_PRIVILEGE_NOT_HELD;
    00380             }
    00381
    00382         ExReadyForErrors = FALSE;
    00383         }
    00384
    00385     Process = PsGetCurrentProcess();
    00386
    00387     //
    00388     // If the default handler is not installed, then
    00389     // call the fatal hard error handler if the error
    00390     // status is error
    00391     //
    00392     // Let GDI override this since it does not want to crash the machine
    00393     // when a bad driver was loaded via MmLoadSystemImage.
    00394     //
    00395
    00396     if ( !(PsGetCurrentThread()->HardErrorsAreDisabled) ) {
    00397
    00398         if (ExReadyForErrors == FALSE && NT_ERROR(ErrorStatus)){
    00399             ExpSystemErrorHandler(
    00400                 ErrorStatus,
    00401                 NumberOfParameters,
    00402                 UnicodeStringParameterMask,
    00403                 Parameters,
    00404                 (BOOLEAN)((PreviousMode != KernelMode) ? TRUE : FALSE)
    00405                 );
    00406             }
    00407         }
    00408
    00409     //
    00410     // If the process has an error port, then if it wants default
    00411     // handling, use its port. If it disabled default handling, then
    00412     // return the error to the caller. If the process does not
    00413     // have a port, then use the registered default handler.
    00414     //
    00415
    00416     if ( Process->ExceptionPort ) {
    00417         if ( Process->DefaultHardErrorProcessing & 1 ) {
    00418             ErrorPort = Process->ExceptionPort;
    00419             }
    00420         else {
    00421
    00422             //
    00423             // if error processing is disabled, check the error override
    00424             // status
    00425             //
    00426             if ( ErrorStatus & HARDERROR_OVERRIDE_ERRORMODE ) {
    00427                 ErrorPort = Process->ExceptionPort;
    00428                 }
    00429             else {
    00430                 ErrorPort = NULL;
    00431                 }
    00432             }
    00433         }
    00434     else {
    00435         if ( Process->DefaultHardErrorProcessing & 1 ) {
    00436             ErrorPort = ExpDefaultErrorPort;
    00437             }
    00438         else {
    00439
    00440             //
    00441             // if error processing is disabled, check the error override
    00442             // status
    00443             //
    00444
    00445             if ( ErrorStatus & HARDERROR_OVERRIDE_ERRORMODE ) {
    00446                 ErrorPort = ExpDefaultErrorPort;
    00447                 }
    00448             else {
    00449                 ErrorPort = NULL;
    00450                 }
    00451             ErrorPort = NULL;
    00452             }
    00453         }
    00454
    00455     if ( PsGetCurrentThread()->HardErrorsAreDisabled ) {
    00456         ErrorPort = NULL;
    00457         }
    00458
    00459     if ( !IS_SYSTEM_THREAD(PsGetCurrentThread()) ) {
    00460         try {
    00461             PTEB Teb;
    00462             Teb = (PTEB)PsGetCurrentThread()->Tcb.Teb;
    00463             if ( Teb->HardErrorsAreDisabled ) {
    00464                 ErrorPort = NULL;
    00465                 }
    00466             }
    00467         except (EXCEPTION_EXECUTE_HANDLER) {
    00468             ;
    00469             }
    00470         }
    00471
    00472     if ( ErrorPort ) {
    00473         if ( Process == ExpDefaultErrorPortProcess ) {
    00474             if ( NT_ERROR(ErrorStatus) ) {
    00475                 ExpSystemErrorHandler(
    00476                     ErrorStatus,
    00477                     NumberOfParameters,
    00478                     UnicodeStringParameterMask,
    00479                     Parameters,
    00480                     (BOOLEAN)((PreviousMode != KernelMode) ? TRUE : FALSE)
    00481                     );
    00482                 }
    00483             *Response = (ULONG)ResponseReturnToCaller;
    00484             Status = STATUS_SUCCESS;
    00485             return Status;
    00486             }
    00487         m->h.u1.Length = HARDERROR_API_MSG_LENGTH;
    00488         m->h.u2.ZeroInit = LPC_ERROR_EVENT;
    00489         m->Status = ErrorStatus & ~HARDERROR_OVERRIDE_ERRORMODE;
    00490         m->ValidResponseOptions = ValidResponseOptions;
    00491         m->UnicodeStringParameterMask = UnicodeStringParameterMask;
    00492         m->NumberOfParameters = NumberOfParameters;
    00493         if ( Parameters ) {
    00494             RtlMoveMemory(&m->Parameters,Parameters, sizeof(ULONG_PTR)*NumberOfParameters);
    00495             }
    00496         KeQuerySystemTime(&m->ErrorTime);
    00497
    00498         Status = LpcRequestWaitReplyPort(
    00499                     ErrorPort,
    00500                     (PPORT_MESSAGE) m,
    00501                     (PPORT_MESSAGE) m
    00502                     );
    00503         if ( NT_SUCCESS(Status) ) {
    00504             switch ( m->Response ) {
    00505                 case ResponseReturnToCaller :
    00506                 case ResponseNotHandled :
    00507                 case ResponseAbort :
    00508                 case ResponseCancel :
    00509                 case ResponseIgnore :
    00510                 case ResponseNo :
    00511                 case ResponseOk :
    00512                 case ResponseRetry :
    00513                 case ResponseYes :
    00514                 case ResponseTryAgain :
    00515                 case ResponseContinue :
    00516                     break;
    00517                 default:
    00518                     m->Response = (ULONG)ResponseReturnToCaller;
    00519                     break;
    00520                 }
    00521             *Response = m->Response;
    00522             }
    00523         }
    00524     else {
    00525         *Response = (ULONG)ResponseReturnToCaller;
    00526         Status = STATUS_SUCCESS;
    00527         }
    00528     return Status;
    00529 }

VOID ExpSystemErrorHandler | ( | IN NTSTATUS | ErrorStatus,
|  | IN ULONG | NumberOfParameters,
|  | IN ULONG | UnicodeStringParameterMask,
|  | IN PULONG_PTR | Parameters,
|  | IN BOOLEAN | CallShutdown
| ) |

Definition at line 64 of file ex/harderr.c.

References ASSERT, CHAR, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExpSystemErrorHandler(), FALSE, KeBugCheckEx(), KeGetCurrentPrcb, KiSaveProcessorControlState(), NlsMbCodePageTag, NonPagedPool, NT_SUCCESS, NTSTATUS(), PoShutdownBugCheck(), PsSystemDllDllBase, RtlAnsiStringToUnicodeString(), RtlFindMessage(), RtlInitAnsiString(), RtlInitUnicodeString(), RtlUnicodeStringToAnsiString(), RtlUnicodeStringToOemString(), Status, strlen(), TRUE, and USHORT.

Referenced by ExpRaiseHardError(), and ExpSystemErrorHandler().

    00071 {
    00072
    00073     ULONG Counter;
    00074     ANSI_STRING AnsiString;
    00075     NTSTATUS Status;
    00076     ULONG_PTR ParameterVector[MAXIMUM_HARDERROR_PARAMETERS];
    00077     CHAR DefaultFormatBuffer[32];
    00078     CHAR ExpSystemErrorBuffer[256];
    00079     PMESSAGE_RESOURCE_ENTRY MessageEntry;
    00080     PSZ ErrorCaption;
    00081     PSZ ErrorFormatString;
    00082     ANSI_STRING Astr;
    00083     UNICODE_STRING Ustr;
    00084     OEM_STRING Ostr;
    00085     PSZ OemCaption;
    00086     PSZ OemMessage;
    00087     PSZ UnknownHardError = "Unknown Hard Error";
    00088     PVOID UnlockHandle;
    00089     CONTEXT ContextSave;
    00090
    00091     //
    00092     // This handler is called whenever a hard error occurs before the
    00093     // default handler has been installed.
    00094     //
    00095     // This is done regardless of whether or not the process has chosen
    00096     // default hard error processing.
    00097     //
    00098
    00099
    00100     //
    00101     // Capture the callers context as closely as possible into the debugger's
    00102     // processor state area of the Prcb
    00103     //
    00104     // N.B. There may be some prologue code that shuffles registers such that
    00105     //      they get destroyed.
    00106     //
    00107     // this code is here only for crash dumps
    00108     RtlCaptureContext(&KeGetCurrentPrcb()->ProcessorState.ContextFrame);
    00109     KiSaveProcessorControlState(&KeGetCurrentPrcb()->ProcessorState);
    00110     ContextSave = KeGetCurrentPrcb()->ProcessorState.ContextFrame;
    00111
    00112
    00113     DefaultFormatBuffer[0] = '\0';
    00114     RtlZeroMemory(ParameterVector,sizeof(ParameterVector));
    00115     for(Counter=0;Counter < NumberOfParameters;Counter++){
    00116         ParameterVector[Counter] = Parameters[Counter];
    00117         }
    00118
    00119     for(Counter=0;Counter < NumberOfParameters;Counter++){
    00120         if ( UnicodeStringParameterMask & 1<<Counter ) {
    00121             strcat(DefaultFormatBuffer," %s");
    00122             RtlUnicodeStringToAnsiString(&AnsiString,(PUNICODE_STRING)Parameters[Counter],TRUE);
    00123             ParameterVector[Counter] = (ULONG_PTR)AnsiString.Buffer;
    00124             }
    00125         else {
    00126             strcat(DefaultFormatBuffer," %x");
    00127             }
    00128         }
    00129     strcat(DefaultFormatBuffer,"\n");
    00130
    00131     //
    00132     // HELP where do I get the resource from !
    00133     //
    00134
    00135     if ( PsSystemDllDllBase ) {
    00136
    00137         try {
    00138
    00139             //
    00140             // If we are on a DBCS code page, we have to use ENGLISH resource
    00141             // instead of default resource because HalDisplayString() can only
    00142             // display ASCII characters on the blue screen.
    00143             //
    00144
    00145             Status = RtlFindMessage(PsSystemDllDllBase,
    00146                                     11,
    00147                                     NlsMbCodePageTag ?
    00148                                     MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US) :
    00149                                     0,
    00150                                     ErrorStatus,
    00151                                     &MessageEntry);
    00152
    00153             if (!NT_SUCCESS(Status)) {
    00154                 ErrorCaption = ErrorFormatString = UnknownHardError;
    00155                 }
    00156             else {
    00157                 if (MessageEntry->Flags & MESSAGE_RESOURCE_UNICODE) {
    00158
    00159                     //
    00160                     // Message resource is Unicode.  Convert to ANSI
    00161                     //
    00162
    00163                     RtlInitUnicodeString(&Ustr, (PCWSTR)MessageEntry->Text);
    00164                     Astr.Length = (USHORT) RtlUnicodeStringToAnsiSize(&Ustr);
    00165                     ErrorCaption = ExAllocatePoolWithTag(NonPagedPool,Astr.Length+16, ' rrE');
    00166
    00167                     if (ErrorCaption) {
    00168                         Astr.MaximumLength = Astr.Length + 16;
    00169                         Astr.Buffer = ErrorCaption;
    00170                         Status = RtlUnicodeStringToAnsiString(&Astr, &Ustr, FALSE);
    00171                         if ( !NT_SUCCESS(Status) ) {
    00172                             ExFreePool(ErrorCaption);
    00173                             ErrorCaption = ErrorFormatString = UnknownHardError;
    00174                             }
    00175                         }
    00176                     else {
    00177                         ErrorCaption = ErrorFormatString = UnknownHardError;
    00178                         }
    00179
    00180                     }
    00181                 else {
    00182                     ErrorCaption = ExAllocatePoolWithTag(NonPagedPool,strlen(MessageEntry->Text)+16, ' rrE');
    00183                     if ( ErrorCaption ) {
    00184                         strcpy(ErrorCaption,MessageEntry->Text);
    00185                         }
    00186                     else {
    00187                         ErrorCaption = ErrorFormatString = UnknownHardError;
    00188                         }
    00189                     }
    00190
    00191                 if (ErrorCaption != UnknownHardError) {
    00192                     //
    00193                     // It's assumed the Error String from the message table is in the format:
    00194                     // {ErrorCaption}\r\n\0ErrorFormatString\0.  Parse out the caption.
    00195                     //
    00196                     ErrorFormatString = ErrorCaption;
    00197                     Counter = strlen(ErrorCaption);
    00198                     while ( Counter && *ErrorFormatString >= ' ' ) {
    00199                         ErrorFormatString++;
    00200                         Counter--;
    00201                         }
    00202
    00203                     *ErrorFormatString++ = '\0';
    00204                     Counter--;
    00205
    00206                     while ( Counter && *ErrorFormatString && *ErrorFormatString <= ' ') {
    00207                         ErrorFormatString++;
    00208                         Counter--;
    00209                         }
    00210                     }
    00211
    00212                     if (!Counter) {
    00213                         // Oops - Bad Format String.
    00214                         ErrorFormatString = "";
    00215                     }
    00216                 }
    00217             }
    00218         except ( EXCEPTION_EXECUTE_HANDLER ) {
    00219             ErrorFormatString = UnknownHardError;
    00220             ErrorCaption = UnknownHardError;
    00221             }
    00222         }
    00223     else {
    00224         ErrorFormatString = DefaultFormatBuffer;
    00225         ErrorCaption = UnknownHardError;
    00226         }
    00227
    00228     try {
    00229         _snprintf( ExpSystemErrorBuffer, sizeof( ExpSystemErrorBuffer ),
    00230                    "\nSTOP: %lx %s\n", ErrorStatus,ErrorCaption);
    00231         }
    00232     except(EXCEPTION_EXECUTE_HANDLER) {
    00233         _snprintf( ExpSystemErrorBuffer, sizeof( ExpSystemErrorBuffer ),
    00234                    "\nHardError %lx\n", ErrorStatus);
    00235         }
    00236
    00237     UnlockHandle = MmLockPagableCodeSection((PVOID)ExpSystemErrorHandler);
    00238     ASSERT(UnlockHandle);
    00239
    00240     //
    00241     // take the caption and convert it to OEM
    00242     //
    00243
    00244     OemCaption = UnknownHardError;
    00245     OemMessage = UnknownHardError;
    00246
    00247     RtlInitAnsiString(&Astr,ExpSystemErrorBuffer);
    00248     Status = RtlAnsiStringToUnicodeString(&Ustr,&Astr,TRUE);
    00249     if ( !NT_SUCCESS(Status) ) {
    00250         goto punt1;
    00251         }
    00252
    00253     //
    00254     // Allocate the OEM string out of nonpaged pool so that bugcheck
    00255     // can read it.
    00256     //
    00257     Ostr.Length = (USHORT)RtlUnicodeStringToOemSize(&Ustr);
    00258     Ostr.MaximumLength = Ostr.Length;
    00259     Ostr.Buffer = ExAllocatePoolWithTag(NonPagedPool, Ostr.Length, ' rrE');
    00260     OemCaption = Ostr.Buffer;
    00261     if (Ostr.Buffer) {
    00262         Status = RtlUnicodeStringToOemString(&Ostr,&Ustr,FALSE);
    00263         if ( !NT_SUCCESS(Status) ) {
    00264             goto punt1;
    00265             }
    00266         }
    00267
    00268     //
    00269     // Can't do much of anything after calling HalDisplayString...
    00270     //
    00271
    00272 punt1:;
    00273     try {
    00274         _snprintf( ExpSystemErrorBuffer, sizeof( ExpSystemErrorBuffer ),
    00275                    ErrorFormatString,
    00276                    ParameterVector[0],
    00277                    ParameterVector[1],
    00278                    ParameterVector[2],
    00279                    ParameterVector[3]
    00280                  );
    00281         }
    00282     except(EXCEPTION_EXECUTE_HANDLER) {
    00283         _snprintf( ExpSystemErrorBuffer, sizeof( ExpSystemErrorBuffer ),
    00284                    "Exception Processing Message %lx Parameters %lx %lx %lx %lx",
    00285                    ErrorStatus,
    00286                    ParameterVector[0],
    00287                    ParameterVector[1],
    00288                    ParameterVector[2],
    00289                    ParameterVector[3]
    00290                  );
    00291         }
    00292
    00293
    00294     RtlInitAnsiString(&Astr,ExpSystemErrorBuffer);
    00295     Status = RtlAnsiStringToUnicodeString(&Ustr,&Astr,TRUE);
    00296     if ( !NT_SUCCESS(Status) ) {
    00297         goto punt2;
    00298         }
    00299     //
    00300     // Allocate the OEM string out of nonpaged pool so that bugcheck
    00301     // can read it.
    00302     //
    00303     Ostr.Length = (USHORT)RtlUnicodeStringToOemSize(&Ustr);
    00304     Ostr.MaximumLength = Ostr.Length;
    00305     Ostr.Buffer = ExAllocatePoolWithTag(NonPagedPool, Ostr.Length, ' rrE');
    00306     OemMessage = Ostr.Buffer;
    00307     if (Ostr.Buffer) {
    00308         Status = RtlUnicodeStringToOemString(&Ostr,&Ustr,FALSE);
    00309         if ( !NT_SUCCESS(Status) ) {
    00310             goto punt2;
    00311             }
    00312         }
    00313
    00314 punt2:;
    00315     ASSERT(sizeof(PVOID) == sizeof(ULONG_PTR));
    00316     ASSERT(sizeof(ULONG) == sizeof(NTSTATUS));
    00317
    00318     //
    00319     // We don't come back from here.
    00320     //
    00321
    00322     if (CallShutdown) {
    00323
    00324         PoShutdownBugCheck(
    00325             FALSE,
    00326             FATAL_UNHANDLED_HARD_ERROR,
    00327             (ULONG)ErrorStatus,
    00328             (ULONG_PTR)&(ParameterVector[0]),
    00329             (ULONG_PTR)OemCaption,
    00330             (ULONG_PTR)OemMessage
    00331             );
    00332
    00333         }
    00334     else {
    00335
    00336         KeBugCheckEx(
    00337             FATAL_UNHANDLED_HARD_ERROR,
    00338             (ULONG)ErrorStatus,
    00339             (ULONG_PTR)&(ParameterVector[0]),
    00340             (ULONG_PTR)OemCaption,
    00341             (ULONG_PTR)OemMessage
    00342             );
    00343
    00344         }
    00345
    00346 }

NTSTATUS ExRaiseHardError | ( | IN NTSTATUS | ErrorStatus,
|  | IN ULONG | NumberOfParameters,
|  | IN ULONG | UnicodeStringParameterMask,
|  | IN PULONG_PTR | Parameters,
|  | IN ULONG | ValidResponseOptions,
|  | OUT PULONG | Response
| ) |

Definition at line 700 of file ex/harderr.c.

References Buffer, ExpRaiseHardError(), ExpTooLateForErrors, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and Status.

Referenced by CmpDiskFullWarningWorker(), CmpInitializeHiveList(), CmpQuotaWarningWorker(), IopHardErrorThread(), IopRaiseHardError(), IopRaiseInformationalHardError(), NtRaiseHardError(), and xxxCreateThreadInfo().

    00708 {
    00709     NTSTATUS Status;
    00710     PULONG_PTR ParameterBlock;
    00711     PULONG_PTR UserModeParameterBase;
    00712     PUNICODE_STRING UserModeStringsBase;
    00713     PUCHAR UserModeStringDataBase;
    00714     UNICODE_STRING CapturedStrings[MAXIMUM_HARDERROR_PARAMETERS];
    00715     ULONG LocalResponse;
    00716     ULONG Counter;
    00717     SIZE_T UserModeSize;
    00718
    00719     PAGED_CODE();
    00720
    00721     //
    00722     //  If we are in the process of shuting down the system, do not allow
    00723     //  hard errors.
    00724     //
    00725
    00726     if ( ExpTooLateForErrors ) {
    00727
    00728         *Response = ResponseNotHandled;
    00729
    00730         return STATUS_SUCCESS;
    00731     }
    00732
    00733     //
    00734     // If the parameters contain strings, we need to capture
    00735     // the strings and the string descriptors and push them into
    00736     // user-mode.
    00737     //
    00738
    00739     if ( ARGUMENT_PRESENT(Parameters) ) {
    00740         if ( UnicodeStringParameterMask ) {
    00741
    00742             //
    00743             // We have strings. The parameter block and all strings
    00744             // must be pushed into usermode.
    00745             //
    00746
    00747             UserModeSize = (sizeof(ULONG_PTR)+sizeof(UNICODE_STRING))*MAXIMUM_HARDERROR_PARAMETERS;
    00748             UserModeSize += sizeof(UNICODE_STRING);
    00749
    00750             for(Counter=0;Counter < NumberOfParameters;Counter++){
    00751
    00752                 //
    00753                 // if there is a string in this position,
    00754                 // then probe and capture the string
    00755                 //
    00756
    00757                 if ( UnicodeStringParameterMask & 1<<Counter ) {
    00758
    00759                     RtlMoveMemory(
    00760                         &CapturedStrings[Counter],
    00761                         (PVOID)Parameters[Counter],
    00762                         sizeof(UNICODE_STRING)
    00763                         );
    00764
    00765                     UserModeSize += CapturedStrings[Counter].MaximumLength;
    00766
    00767                     }
    00768                 }
    00769
    00770             //
    00771             // Now we have the user-mode size all figured out.
    00772             // Allocate some memory and point to it with the
    00773             // parameter block. Then go through and copy all
    00774             // of the parameters, string descriptors, and
    00775             // string data into the memory
    00776             //
    00777
    00778             ParameterBlock = NULL;
    00779             Status = ZwAllocateVirtualMemory(
    00780                         NtCurrentProcess(),
    00781                         (PVOID *)&ParameterBlock,
    00782                         0,
    00783                         &UserModeSize,
    00784                         MEM_COMMIT,
    00785                         PAGE_READWRITE
    00786                         );
    00787
    00788             if (!NT_SUCCESS( Status )) {
    00789                 return( Status );
    00790                 }
    00791
    00792             UserModeParameterBase = ParameterBlock;
    00793             UserModeStringsBase = (PUNICODE_STRING)((PUCHAR)ParameterBlock + sizeof(ULONG)*MAXIMUM_HARDERROR_PARAMETERS);
    00794             UserModeStringDataBase = (PUCHAR)UserModeStringsBase + sizeof(UNICODE_STRING)*MAXIMUM_HARDERROR_PARAMETERS;
    00795
    00796             for(Counter=0;Counter < NumberOfParameters;Counter++){
    00797
    00798                 //
    00799                 // move parameters to user-mode portion of the
    00800                 // address space.
    00801                 //
    00802
    00803                 if ( UnicodeStringParameterMask & 1<<Counter ) {
    00804
    00805                     //
    00806                     // fix the parameter to point at the string descriptor slot
    00807                     // in the user-mode buffer.
    00808                     //
    00809
    00810                     UserModeParameterBase[Counter] = (ULONG_PTR)&UserModeStringsBase[Counter];
    00811
    00812                     //
    00813                     // Copy the string data to user-mode
    00814                     //
    00815
    00816                     RtlMoveMemory(
    00817                         UserModeStringDataBase,
    00818                         CapturedStrings[Counter].Buffer,
    00819                         CapturedStrings[Counter].MaximumLength
    00820                         );
    00821
    00822                     CapturedStrings[Counter].Buffer = (PWSTR)UserModeStringDataBase;
    00823
    00824                     //
    00825                     // copy the string descriptor
    00826                     //
    00827
    00828                     RtlMoveMemory(
    00829                         &UserModeStringsBase[Counter],
    00830                         &CapturedStrings[Counter],
    00831                         sizeof(UNICODE_STRING)
    00832                         );
    00833
    00834                     //
    00835                     // Adjust the string data base
    00836                     //
    00837
    00838                     UserModeStringDataBase += CapturedStrings[Counter].MaximumLength;
    00839
    00840                     }
    00841                 else {
    00842                     UserModeParameterBase[Counter] = Parameters[Counter];
    00843                     }
    00844                 }
    00845             }
    00846         else {
    00847             ParameterBlock = Parameters;
    00848             }
    00849         }
    00850     else {
    00851         ParameterBlock = NULL;
    00852         }
    00853
    00854     //
    00855     // Call the hard error sender.
    00856     //
    00857
    00858     Status = ExpRaiseHardError(
    00859                 ErrorStatus,
    00860                 NumberOfParameters,
    00861                 UnicodeStringParameterMask,
    00862                 ParameterBlock,
    00863                 ValidResponseOptions,
    00864                 &LocalResponse
    00865                 );
    00866     //
    00867     // If the parameter block was allocated, it needs to be
    00868     // freed
    00869     //
    00870
    00871     if ( ParameterBlock && ParameterBlock != Parameters ) {
    00872         UserModeSize = 0;
    00873         ZwFreeVirtualMemory(
    00874               NtCurrentProcess(),
    00875               (PVOID *)&ParameterBlock,
    00876               &UserModeSize,
    00877               MEM_RELEASE
    00878               );
    00879         }
    00880     *Response = LocalResponse;
    00881
    00882     return Status;
    00883 }

NTSTATUS NtRaiseHardError | ( | IN NTSTATUS | ErrorStatus,
|  | IN ULONG | NumberOfParameters,
|  | IN ULONG | UnicodeStringParameterMask,
|  | IN PULONG_PTR | Parameters,
|  | IN ULONG | ValidResponseOptions,
|  | OUT PULONG | Response
| ) |

Definition at line 532 of file ex/harderr.c.

References DbgPrint, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExpRaiseHardError(), ExRaiseHardError(), KdDebuggerEnabled, KernelMode, KPROCESSOR_MODE, NTSTATUS(), NULL, PAGED_CODE, PagedPool, ProbeForRead, ProbeForWriteUlong, and Status.

Referenced by LdrpCreateDllSection(), LdrpInitializationFailure(), LdrpMapDll(), LdrpSnapThunk(), PsLocateSystemDll(), and ServiceMessageBox().

    00540 {
    00541     NTSTATUS Status;
    00542     PULONG_PTR CapturedParameters;
    00543     KPROCESSOR_MODE PreviousMode;
    00544     ULONG LocalResponse;
    00545     UNICODE_STRING CapturedString;
    00546     ULONG Counter;
    00547
    00548     PAGED_CODE();
    00549
    00550     if ( NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS ) {
    00551         return STATUS_INVALID_PARAMETER_2;
    00552     }
    00553
    00554     if ( ARGUMENT_PRESENT(Parameters) && NumberOfParameters == 0 ) {
    00555         return STATUS_INVALID_PARAMETER_2;
    00556     }
    00557
    00558     PreviousMode = KeGetPreviousMode();
    00559     if (PreviousMode != KernelMode) {
    00560         switch ( ValidResponseOptions ) {
    00561             case OptionAbortRetryIgnore :
    00562             case OptionOk :
    00563             case OptionOkCancel :
    00564             case OptionRetryCancel :
    00565             case OptionYesNo :
    00566             case OptionYesNoCancel :
    00567             case OptionShutdownSystem :
    00568             case OptionOkNoWait :
    00569             case OptionCancelTryContinue:
    00570                 break;
    00571             default :
    00572                 return STATUS_INVALID_PARAMETER_4;
    00573             }
    00574
    00575         CapturedParameters = NULL;
    00576         try {
    00577             ProbeForWriteUlong(Response);
    00578
    00579             if ( ARGUMENT_PRESENT(Parameters) ) {
    00580                 ProbeForRead(
    00581                     Parameters,
    00582                     sizeof(ULONG_PTR)*NumberOfParameters,
    00583                     sizeof(ULONG_PTR)
    00584                     );
    00585                 CapturedParameters = ExAllocatePoolWithTag(PagedPool,sizeof(ULONG_PTR)*NumberOfParameters, ' rrE');
    00586                 if ( !CapturedParameters ) {
    00587                     return STATUS_NO_MEMORY;
    00588                     }
    00589                 RtlMoveMemory(CapturedParameters,Parameters,sizeof(ULONG_PTR)*NumberOfParameters);
    00590
    00591                 //
    00592                 // probe all strings
    00593                 //
    00594
    00595                 if ( UnicodeStringParameterMask ) {
    00596                     for(Counter=0;Counter < NumberOfParameters;Counter++){
    00597
    00598                         //
    00599                         // if there is a string in this position,
    00600                         // then probe and capture the string
    00601                         //
    00602
    00603                         if ( UnicodeStringParameterMask & (1<<Counter) ) {
    00604                             ProbeForRead(
    00605                                 (PVOID)CapturedParameters[Counter],
    00606                                 sizeof(UNICODE_STRING),
    00607                                 sizeof(ULONG_PTR)
    00608                                 );
    00609                             RtlMoveMemory(
    00610                                 &CapturedString,
    00611                                 (PVOID)CapturedParameters[Counter],
    00612                                 sizeof(UNICODE_STRING)
    00613                                 );
    00614
    00615                             //
    00616                             // Now probe the string
    00617                             //
    00618
    00619                             ProbeForRead(
    00620                                 CapturedString.Buffer,
    00621                                 CapturedString.MaximumLength,
    00622                                 sizeof(UCHAR)
    00623                                 );
    00624
    00625                             }
    00626                         }
    00627                     }
    00628                 }
    00629             else {
    00630                 CapturedParameters = NULL;
    00631                 }
    00632             }
    00633         except(EXCEPTION_EXECUTE_HANDLER) {
    00634             if ( CapturedParameters ) {
    00635                 ExFreePool(CapturedParameters);
    00636                 }
    00637             return GetExceptionCode();
    00638             }
    00639
    00640         if (ErrorStatus == STATUS_SYSTEM_IMAGE_BAD_SIGNATURE && KdDebuggerEnabled) {
    00641             if (NumberOfParameters && CapturedParameters) {
    00642                 DbgPrint("****************************************************************\n");
    00643                 DbgPrint("* The system detected a bad signature on file %wZ\n",(PUNICODE_STRING)CapturedParameters[0]);
    00644                 DbgPrint("****************************************************************\n");
    00645             }
    00646             if (CapturedParameters) {
    00647                 ExFreePool(CapturedParameters);
    00648             }
    00649             return STATUS_SUCCESS;
    00650         }
    00651
    00652         //
    00653         // Call ExpRaiseHardError. All parameters are probed and everything
    00654         // should be user-mode.
    00655         // ExRaiseHardError will squirt all strings into user-mode
    00656         // without any probing
    00657         //
    00658
    00659         Status = ExpRaiseHardError(
    00660                     ErrorStatus,
    00661                     NumberOfParameters,
    00662                     UnicodeStringParameterMask,
    00663                     CapturedParameters,
    00664                     ValidResponseOptions,
    00665                     &LocalResponse
    00666                     );
    00667         }
    00668     else {
    00669         CapturedParameters = Parameters;
    00670
    00671         Status = ExRaiseHardError(
    00672                     ErrorStatus,
    00673                     NumberOfParameters,
    00674                     UnicodeStringParameterMask,
    00675                     CapturedParameters,
    00676                     ValidResponseOptions,
    00677                     &LocalResponse
    00678                     );
    00679         }
    00680
    00681     if (PreviousMode != KernelMode) {
    00682         if ( CapturedParameters ) {
    00683             ExFreePool(CapturedParameters);
    00684             }
    00685         try {
    00686             *Response = LocalResponse;
    00687             }
    00688         except (EXCEPTION_EXECUTE_HANDLER) {
    00689             return Status;
    00690             }
    00691         }
    00692     else {
    00693         *Response = LocalResponse;
    00694         }
    00695
    00696     return Status;
    00697 }

NTSTATUS NtSetDefaultHardErrorPort | ( | IN HANDLE | DefaultHardErrorPort | ) |

Definition at line 886 of file ex/harderr.c.

References ExpDefaultErrorPort, ExpDefaultErrorPortProcess, ExReadyForErrors, LpcPortObjectType, NT_SUCCESS, NTSTATUS(), NULL, ObReferenceObjectByHandle(), PAGED_CODE, PsGetCurrentProcess, SeSinglePrivilegeCheck(), SeTcbPrivilege, Status, and TRUE.

    00889 {
    00890     NTSTATUS Status;
    00891
    00892     PAGED_CODE();
    00893
    00894     if (!SeSinglePrivilegeCheck( SeTcbPrivilege, KeGetPreviousMode() )) {
    00895         return STATUS_PRIVILEGE_NOT_HELD;
    00896         }
    00897
    00898     if ( ExReadyForErrors ) {
    00899         return STATUS_UNSUCCESSFUL;
    00900         }
    00901
    00902     //
    00903     // Priv check ?
    00904     //
    00905
    00906     Status = ObReferenceObjectByHandle (
    00907                 DefaultHardErrorPort,
    00908                 0,
    00909                 LpcPortObjectType,
    00910                 KeGetPreviousMode(),
    00911                 (PVOID *)&ExpDefaultErrorPort,
    00912                 NULL
    00913                 );
    00914     if ( !NT_SUCCESS(Status) ) {
    00915         return Status;
    00916         }
    00917
    00918     ExReadyForErrors = TRUE;
    00919     ExpDefaultErrorPortProcess = PsGetCurrentProcess();
    00920
    00921     return STATUS_SUCCESS;
    00922 }

## Variable Documentation

HANDLE ExpDefaultErrorPort

| Definition at line 60 of file ex/harderr.c. Referenced by ExpRaiseHardError(), and NtSetDefaultHardErrorPort().

PEPROCESS ExpDefaultErrorPortProcess

| Definition at line 57 of file ex/harderr.c. Referenced by ExpRaiseHardError(), MiCheckForUserStackOverflow(), MiLoadImageSection(), NtSetDefaultHardErrorPort(), and NtSetInformationThread().

BOOLEAN ExpTooLateForErrors = FALSE

| Definition at line 59 of file ex/harderr.c. Referenced by ExRaiseHardError().

BOOLEAN ExReadyForErrors = FALSE

| Definition at line 58 of file ex/harderr.c. Referenced by CmpClaimGlobalQuota(), CmpDiskFullWarning(), ExpRaiseHardError(), IopHardErrorThread(), IopRaiseHardError(), IopRaiseInformationalHardError(), and NtSetDefaultHardErrorPort().

ULONG KeBugCheckCount

| Definition at line 24 of file ex/harderr.c. Referenced by KeBugCheckEx(), and KeEnterKernelDebugger().

ULONG KiBugCheckData[5]

| Definition at line 23 of file ex/harderr.c. Referenced by KeBugCheckEx().

PVOID PsSystemDllDllBase

| Definition at line 61 of file ex/harderr.c. Referenced by ExpSystemErrorHandler(), and PsLocateSystemDll().