Source code of Windows XP (NT5)
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.

316 lines
7.6 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. //save these values in statics so i can see 'em on the debugger............
  55. ExceptionCode = RxExpCode = ExceptionPointer->ExceptionRecord->ExceptionCode;
  56. RxExpAddr = ExceptionPointer->ExceptionRecord->ExceptionAddress;
  57. RxExpEXR = ExceptionPointer->ExceptionRecord;
  58. RxExpCXR = ExceptionPointer->ContextRecord;
  59. RxLog(("!!! %lx %lx %lx %lx\n", RxExpCode, RxExpAddr, RxExpEXR, RxExpCXR));
  60. RxWmiLog(LOG,
  61. RxExceptionFilter_1,
  62. LOGULONG(RxExpCode)
  63. LOGPTR(RxExpAddr)
  64. LOGPTR(RxExpEXR)
  65. LOGPTR(RxExpCXR));
  66. RxDbgTrace(0, (DEBUG_TRACE_UNWIND), ("RxExceptionFilter %X at %X\n", RxExpCode, RxExpAddr));
  67. RxDbgTrace(0, (DEBUG_TRACE_UNWIND), ("RxExceptionFilter EXR=%X, CXR=%X\n", RxExpEXR, RxExpCXR));
  68. if (RxContext == NULL) {
  69. //we cannot do anything even moderately sane
  70. return EXCEPTION_EXECUTE_HANDLER;
  71. }
  72. IF_DEBUG {
  73. if (!FlagOn(RxContext->Flags,RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT)) {
  74. //DbgBreakPoint();
  75. }
  76. }
  77. //
  78. // If the exception is RxStatus(IN_PAGE_ERROR), get the I/O error code
  79. // from the exception record.
  80. //
  81. if (ExceptionCode == STATUS_IN_PAGE_ERROR) {
  82. RxLog(("InPageError...."));
  83. RxWmiLog(LOG,
  84. RxExceptionFilter_2,
  85. LOGPTR(RxContext));
  86. if (ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
  87. ExceptionCode = (NTSTATUS)ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
  88. }
  89. }
  90. #if 0
  91. this code was used back when we thought we could do something sane w/o a context........as it stands now
  92. we cannot call RxProcessException without a context so we might as well punt right now.......... actually,
  93. the punting code is earlier......
  94. //
  95. // If there is not an irp context, we must have had insufficient resources.
  96. //
  97. // if ( !ARGUMENT_PRESENT( RxContext )
  98. // || ( RxContext->MajorFunction == IRP_MJ_CLOSE ) ) {
  99. if ( RxContext==NULL ) {
  100. ASSERT(ExceptionCode==STATUS_INSUFFICIENT_RESOURCES);
  101. if (!FsRtlIsNtstatusExpected( ExceptionCode )) {
  102. RxBugCheck( (ULONG)ExceptionPointer->ExceptionRecord,
  103. (ULONG)ExceptionPointer->ContextRecord,
  104. (ULONG)ExceptionPointer->ExceptionRecord->ExceptionAddress );
  105. }
  106. return EXCEPTION_EXECUTE_HANDLER;
  107. }
  108. #endif
  109. if ( RxContext->StoredStatus == 0 ) {
  110. if (FsRtlIsNtstatusExpected( ExceptionCode )) {
  111. RxContext->StoredStatus = ExceptionCode;
  112. return EXCEPTION_EXECUTE_HANDLER;
  113. } else {
  114. RxBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
  115. (ULONG_PTR)ExceptionPointer->ContextRecord,
  116. (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
  117. }
  118. } else {
  119. //
  120. // We raised this code explicitly ourselves, so it had better be
  121. // expected.
  122. //
  123. ASSERT( FsRtlIsNtstatusExpected( ExceptionCode ) );
  124. }
  125. return EXCEPTION_EXECUTE_HANDLER;
  126. }
  127. NTSTATUS
  128. RxProcessException (
  129. IN PRX_CONTEXT RxContext,
  130. IN NTSTATUS ExceptionCode
  131. )
  132. /*++
  133. Routine Description:
  134. This routine processes an exception. It either completes the request
  135. with the saved exception status or it bugchecks
  136. Arguments:
  137. RxContext - Context of the current operation
  138. ExceptionCode - Supplies the normalized exception status being handled
  139. Return Value:
  140. RXSTATUS - Returns the results of either posting the Irp or the
  141. saved completion status.
  142. --*/
  143. {
  144. PAGED_CODE();
  145. RxDbgTrace(0, Dbg, ("RxProcessException\n", 0));
  146. if ( RxContext == NULL ) {
  147. // we cannot do anything even moderately sane without a context..........sigh
  148. //DbgBreakPoint();
  149. RxBugCheck( 0,0,0 ); //this shouldn't happen.
  150. }
  151. //
  152. // Get the exception status from RxContext->StoredStatus as stored there by
  153. // the exception filter., and
  154. // reset it. Also copy it to the Irp in case it isn't already there
  155. //
  156. ExceptionCode = RxContext->StoredStatus;
  157. if (!FsRtlIsNtstatusExpected( ExceptionCode )) {
  158. RxBugCheck( 0,0,0 ); //this shouldn't happen. we should have BC'd in the filter
  159. }
  160. if (RxContext->MajorFunction == IRP_MJ_CREATE) {
  161. RxpPrepareCreateContextForReuse(RxContext);
  162. }
  163. {
  164. RxCaptureFcb;
  165. PAGED_CODE();
  166. if (capFcb != NULL) {
  167. if (RxContext->FcbResourceAcquired) {
  168. RxDbgTrace( 0, Dbg,("RxCommonWrite ReleasingFcb\n"));
  169. __RxReleaseFcb(RxContext, (PMRX_FCB)(capFcb)
  170. #ifdef RDBSS_TRACKER
  171. ,__LINE__,__FILE__,0
  172. #endif
  173. );
  174. RxContext->FcbResourceAcquired = FALSE;
  175. }
  176. if (RxContext->FcbPagingIoResourceAcquired) {
  177. RxDbgTrace( 0, Dbg,("RxCommonWrite ReleasingPaginIo\n"));
  178. RxReleasePagingIoResource(capFcb,RxContext);
  179. }
  180. }
  181. }
  182. RxCompleteContextAndReturn( ExceptionCode );
  183. }
  184. VOID
  185. RxPopUpFileCorrupt (
  186. IN PRX_CONTEXT RxContext,
  187. IN PFCB Fcb
  188. )
  189. /*++
  190. Routine Description:
  191. The Following routine makes an informational popup that the file
  192. is corrupt.
  193. Arguments:
  194. Fcb - The file that is corrupt.
  195. Return Value:
  196. None.
  197. --*/
  198. {
  199. PKTHREAD Thread;
  200. RxCaptureRequestPacket;
  201. PAGED_CODE();
  202. //if (Fcb->FullFileName.Buffer == NULL) {
  203. //
  204. // RxSetFullFileNameInFcb( RxContext, Fcb );
  205. //}
  206. //
  207. // We never want to block a system thread waiting for the user to
  208. // press OK.
  209. //
  210. if (IoIsSystemThread(capReqPacket->Tail.Overlay.Thread)) {
  211. Thread = NULL;
  212. } else {
  213. Thread = capReqPacket->Tail.Overlay.Thread;
  214. }
  215. IoRaiseInformationalHardError( STATUS_FILE_CORRUPT_ERROR,
  216. &Fcb->FcbTableEntry.Path, //&Fcb->FullFileName,
  217. Thread);
  218. }
  219.