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.

189 lines
4.4 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. raise.c
  5. Abstract:
  6. This module implements functions to raise and exception and to raise
  7. status.
  8. Author:
  9. David N. Cutler (davec) 28-Oct-2000
  10. Environment:
  11. Any mode.
  12. --*/
  13. #include "ntrtlp.h"
  14. VOID
  15. RtlRaiseException (
  16. IN PEXCEPTION_RECORD ExceptionRecord
  17. )
  18. /*++
  19. Routine Description:
  20. This function raises a software exception by building a context record
  21. and calling the raise exception system service.
  22. Arguments:
  23. ExceptionRecord - Supplies a pointer to an exception record.
  24. Return Value:
  25. None.
  26. --*/
  27. {
  28. CONTEXT ContextRecord;
  29. ULONG64 ControlPc;
  30. ULONG64 EstablisherFrame;
  31. PRUNTIME_FUNCTION FunctionEntry;
  32. PVOID HandlerData;
  33. ULONG64 ImageBase;
  34. NTSTATUS Status = STATUS_INVALID_DISPOSITION;
  35. //
  36. // Capture the current context, unwind to the caller of this routine, set
  37. // the exception address, and call the appropriate exception dispatcher.
  38. //
  39. RtlCaptureContext(&ContextRecord);
  40. ControlPc = ContextRecord.Rip;
  41. FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL);
  42. if (FunctionEntry != NULL) {
  43. RtlVirtualUnwind(UNW_FLAG_NHANDLER,
  44. ImageBase,
  45. ControlPc,
  46. FunctionEntry,
  47. &ContextRecord,
  48. &HandlerData,
  49. &EstablisherFrame,
  50. NULL);
  51. ExceptionRecord->ExceptionAddress = (PVOID)ContextRecord.Rip;
  52. #if defined(NTOS_KERNEL_RUNTIME)
  53. if (RtlDispatchException(ExceptionRecord, &ContextRecord) != FALSE) {
  54. return;
  55. }
  56. Status = ZwRaiseException(ExceptionRecord, &ContextRecord, FALSE);
  57. #else
  58. if (ZwQueryPortInformationProcess() == FALSE) {
  59. if (RtlDispatchException(ExceptionRecord, &ContextRecord) != FALSE) {
  60. return;
  61. }
  62. Status = ZwRaiseException(ExceptionRecord, &ContextRecord, FALSE);
  63. } else {
  64. Status = ZwRaiseException(ExceptionRecord, &ContextRecord, TRUE);
  65. }
  66. #endif
  67. }
  68. //
  69. // There should never be a return from either exception dispatch or the
  70. // system service unless there is a problem with the argument list itself.
  71. // Raise another exception specifying the status value returned.
  72. //
  73. RtlRaiseStatus(Status);
  74. return;
  75. }
  76. #pragma warning(push)
  77. #pragma warning(disable:4717) // recursive function
  78. VOID
  79. RtlRaiseStatus (
  80. IN NTSTATUS Status
  81. )
  82. /*++
  83. Routine Description:
  84. This function raises an exception with the specified status value. The
  85. exception is marked as noncontinuable with no parameters.
  86. Arguments:
  87. Status - Supplies the status value to be used as the exception code
  88. for the exception that is to be raised.
  89. Return Value:
  90. None.
  91. --*/
  92. {
  93. CONTEXT ContextRecord;
  94. EXCEPTION_RECORD ExceptionRecord;
  95. //
  96. // Capure the current context and construct an exception record.
  97. //
  98. RtlCaptureContext(&ContextRecord);
  99. ExceptionRecord.ExceptionCode = Status;
  100. ExceptionRecord.ExceptionRecord = NULL;
  101. ExceptionRecord.NumberParameters = 0;
  102. ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  103. ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Rip;
  104. //
  105. // Attempt to dispatch the exception.
  106. //
  107. // N.B. This exception is non-continuable.
  108. //
  109. #if defined(NTOS_KERNEL_RUNTIME)
  110. RtlDispatchException(&ExceptionRecord, &ContextRecord);
  111. Status = ZwRaiseException(&ExceptionRecord, &ContextRecord, FALSE);
  112. #else
  113. if (ZwQueryPortInformationProcess() == FALSE) {
  114. RtlDispatchException(&ExceptionRecord, &ContextRecord);
  115. Status = ZwRaiseException(&ExceptionRecord, &ContextRecord, FALSE);
  116. } else {
  117. Status = ZwRaiseException(&ExceptionRecord, &ContextRecord, TRUE);
  118. }
  119. #endif
  120. //
  121. // There should never be a return from either exception dispatch or the
  122. // system service unless there is a problem with the argument list itself.
  123. // Raise another exception specifying the status value returned.
  124. //
  125. RtlRaiseStatus(Status);
  126. return;
  127. }
  128. #pragma warning(pop)