Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
6.7 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. NtExcept.c
  5. Abstract:
  6. This module declares the exception handlers for the NTwrapper.
  7. Author:
  8. JoeLinn [JoeLinn] 1-Dec-94
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "stdarg.h"
  14. #include "stdio.h"
  15. #include "string.h"
  16. #include "prefix.h"
  17. //
  18. // The Bug check file id for this module
  19. //
  20. #define BugCheckFileId (RDBSS_BUG_CHECK_NTEXCEPT)
  21. //
  22. // The debug trace level
  23. //
  24. #define Dbg (DEBUG_TRACE_CATCH_EXCEPTIONS)
  25. #ifdef ALLOC_PRAGMA
  26. #pragma alloc_text(PAGE, RxProcessException)
  27. #pragma alloc_text(PAGE, RxPopUpFileCorrupt)
  28. #endif
  29. PCONTEXT RxExpCXR;
  30. PEXCEPTION_RECORD RxExpEXR;
  31. PVOID RxExpAddr;
  32. NTSTATUS RxExpCode;
  33. LONG
  34. RxExceptionFilter (
  35. IN PRX_CONTEXT RxContext,
  36. IN PEXCEPTION_POINTERS ExceptionPointer
  37. )
  38. /*++
  39. Routine Description:
  40. This routine is used to decide if we should or should not handle
  41. an exception status that is being raised. It first determines the true exception
  42. code by examining the exception record. If there is an Irp Context, then it inserts the status
  43. into the RxContext. Finally, it determines whether to handle the exception or bugcheck
  44. according to whether the except is one of the expected ones. in actuality, all exceptions are expected
  45. except for some lowlevel machine errors (see fsrtl\filter.c)
  46. Arguments:
  47. RxContext - the irp context of current operation for storing away the code.
  48. ExceptionPointer - Supplies the exception context.
  49. Return Value:
  50. ULONG - returns EXCEPTION_EXECUTE_HANDLER or bugchecks
  51. --*/
  52. {
  53. NTSTATUS ExceptionCode;
  54. //
  55. // save these values in statics so i can see them on the debugger............
  56. //
  57. ExceptionCode = RxExpCode = ExceptionPointer->ExceptionRecord->ExceptionCode;
  58. RxExpAddr = ExceptionPointer->ExceptionRecord->ExceptionAddress;
  59. RxExpEXR = ExceptionPointer->ExceptionRecord;
  60. RxExpCXR = ExceptionPointer->ContextRecord;
  61. RxLog(( "!!! %lx %lx %lx %lx\n", RxExpCode, RxExpAddr, RxExpEXR, RxExpCXR ));
  62. RxWmiLog( LOG,
  63. RxExceptionFilter_1,
  64. LOGULONG( RxExpCode )
  65. LOGPTR( RxExpAddr )
  66. LOGPTR( RxExpEXR )
  67. LOGPTR( RxExpCXR ) );
  68. RxDbgTrace( 0, (DEBUG_TRACE_UNWIND), ("RxExceptionFilter %X at %X\n", RxExpCode, RxExpAddr) );
  69. RxDbgTrace( 0, (DEBUG_TRACE_UNWIND), ("RxExceptionFilter EXR=%X, CXR=%X\n", RxExpEXR, RxExpCXR) );
  70. if (RxContext == NULL) {
  71. //
  72. // we cannot do anything even moderately sane
  73. //
  74. return EXCEPTION_EXECUTE_HANDLER;
  75. }
  76. //
  77. // If the exception is RxStatus(IN_PAGE_ERROR), get the I/O error code
  78. // from the exception record.
  79. //
  80. if (ExceptionCode == STATUS_IN_PAGE_ERROR) {
  81. RxLog(( "InPageError...." ));
  82. RxWmiLog( LOG,
  83. RxExceptionFilter_2,
  84. LOGPTR( RxContext ) );
  85. if (ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
  86. ExceptionCode = (NTSTATUS)ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
  87. }
  88. }
  89. if (RxContext->StoredStatus == 0) {
  90. if (FsRtlIsNtstatusExpected( ExceptionCode )) {
  91. RxContext->StoredStatus = ExceptionCode;
  92. return EXCEPTION_EXECUTE_HANDLER;
  93. } else {
  94. RxBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
  95. (ULONG_PTR)ExceptionPointer->ContextRecord,
  96. (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
  97. }
  98. } else {
  99. //
  100. // We raised this code explicitly ourselves, so it had better be
  101. // expected.
  102. //
  103. ASSERT( FsRtlIsNtstatusExpected( ExceptionCode ) );
  104. }
  105. return EXCEPTION_EXECUTE_HANDLER;
  106. }
  107. NTSTATUS
  108. RxProcessException (
  109. IN PRX_CONTEXT RxContext,
  110. IN NTSTATUS ExceptionCode
  111. )
  112. /*++
  113. Routine Description:
  114. This routine processes an exception. It either completes the request
  115. with the saved exception status or it bugchecks
  116. Arguments:
  117. RxContext - Context of the current operation
  118. ExceptionCode - Supplies the normalized exception status being handled
  119. Return Value:
  120. RXSTATUS - Returns the results of either posting the Irp or the
  121. saved completion status.
  122. --*/
  123. {
  124. PFCB Fcb;
  125. PAGED_CODE();
  126. RxDbgTrace(0, Dbg, ("RxProcessException\n", 0));
  127. if (RxContext == NULL) {
  128. //
  129. // we cannot do anything even moderately sane without a context..........sigh
  130. //
  131. RxBugCheck( 0,0,0 ); // this shouldn't happen.
  132. }
  133. //
  134. // Get the exception status from RxContext->StoredStatus as stored there by
  135. // the exception filter., and
  136. // reset it. Also copy it to the Irp in case it isn't already there
  137. //
  138. ExceptionCode = RxContext->StoredStatus;
  139. if (!FsRtlIsNtstatusExpected( ExceptionCode )) {
  140. RxBugCheck( 0,0,0 ); //this shouldn't happen. we should have BC'd in the filter
  141. }
  142. if (RxContext->MajorFunction == IRP_MJ_CREATE) {
  143. RxpPrepareCreateContextForReuse( RxContext );
  144. }
  145. Fcb = (PFCB)RxContext->pFcb;
  146. if (Fcb != NULL) {
  147. if (RxContext->FcbResourceAcquired) {
  148. RxDbgTrace( 0, Dbg,("RxCommonWrite ReleasingFcb\n"));
  149. RxReleaseFcb( RxContext, Fcb );
  150. RxContext->FcbResourceAcquired = FALSE;
  151. }
  152. if (RxContext->FcbPagingIoResourceAcquired) {
  153. RxDbgTrace( 0, Dbg,("RxCommonWrite ReleasingPaginIo\n"));
  154. RxReleasePagingIoResource( RxContext, Fcb );
  155. }
  156. }
  157. RxCompleteContextAndReturn( ExceptionCode );
  158. }
  159. VOID
  160. RxPopUpFileCorrupt (
  161. IN PRX_CONTEXT RxContext,
  162. IN PFCB Fcb
  163. )
  164. /*++
  165. Routine Description:
  166. The Following routine makes an informational popup that the file
  167. is corrupt.
  168. Arguments:
  169. Fcb - The file that is corrupt.
  170. Return Value:
  171. None.
  172. --*/
  173. {
  174. PKTHREAD Thread;
  175. PIRP Irp = RxContext->CurrentIrp;
  176. PAGED_CODE();
  177. //
  178. // We never want to block a system thread waiting for the user to
  179. // press OK.
  180. //
  181. if (IoIsSystemThread( Irp->Tail.Overlay.Thread )) {
  182. Thread = NULL;
  183. } else {
  184. Thread = Irp->Tail.Overlay.Thread;
  185. }
  186. IoRaiseInformationalHardError( STATUS_FILE_CORRUPT_ERROR,
  187. &Fcb->FcbTableEntry.Path, // &Fcb->FullFileName,
  188. Thread );
  189. }
  190.