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.

263 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. dbgkport.c
  5. Abstract:
  6. This module implements the dbg primitives to access a process'
  7. DebugPort and ExceptionPort.
  8. Author:
  9. Mark Lucovsky (markl) 19-Jan-1990
  10. Revision History:
  11. --*/
  12. #include "dbgkp.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGE, DbgkpSendApiMessage)
  15. #pragma alloc_text(PAGE, DbgkForwardException)
  16. #pragma alloc_text(PAGE, DbgkpSendApiMessageLpc)
  17. #endif
  18. NTSTATUS
  19. DbgkpSendApiMessage(
  20. IN OUT PDBGKM_APIMSG ApiMsg,
  21. IN BOOLEAN SuspendProcess
  22. )
  23. /*++
  24. Routine Description:
  25. This function sends the specified API message over the specified
  26. port. It is the caller's responsibility to format the API message
  27. prior to calling this function.
  28. If the SuspendProcess flag is supplied, then all threads in the
  29. calling process are first suspended. Upon receipt of the reply
  30. message, the threads are resumed.
  31. Arguments:
  32. ApiMsg - Supplies the API message to send.
  33. SuspendProcess - A flag that if set to true, causes all of the
  34. threads in the process to be suspended prior to the call,
  35. and resumed upon receipt of a reply.
  36. Return Value:
  37. NTSTATUS.
  38. --*/
  39. {
  40. NTSTATUS st;
  41. PEPROCESS Process;
  42. PAGED_CODE();
  43. if ( SuspendProcess ) {
  44. SuspendProcess = DbgkpSuspendProcess();
  45. }
  46. ApiMsg->ReturnedStatus = STATUS_PENDING;
  47. Process = PsGetCurrentProcess();
  48. PS_SET_BITS (&Process->Flags, PS_PROCESS_FLAGS_CREATE_REPORTED);
  49. st = DbgkpQueueMessage (Process, PsGetCurrentThread (), ApiMsg, 0, NULL);
  50. ZwFlushInstructionCache (NtCurrentProcess (), NULL, 0);
  51. if ( SuspendProcess ) {
  52. DbgkpResumeProcess();
  53. }
  54. return st;
  55. }
  56. NTSTATUS
  57. DbgkpSendApiMessageLpc(
  58. IN OUT PDBGKM_APIMSG ApiMsg,
  59. IN PVOID Port,
  60. IN BOOLEAN SuspendProcess
  61. )
  62. /*++
  63. Routine Description:
  64. This function sends the specified API message over the specified
  65. port. It is the caller's responsibility to format the API message
  66. prior to calling this function.
  67. If the SuspendProcess flag is supplied, then all threads in the
  68. calling process are first suspended. Upon receipt of the reply
  69. message, the threads are resumed.
  70. Arguments:
  71. ApiMsg - Supplies the API message to send.
  72. Port - Supplies the address of a port to send the api message.
  73. SuspendProcess - A flag that if set to true, causes all of the
  74. threads in the process to be suspended prior to the call,
  75. and resumed upon receipt of a reply.
  76. Return Value:
  77. NTSTATUS.
  78. --*/
  79. {
  80. NTSTATUS st;
  81. ULONG_PTR MessageBuffer[PORT_MAXIMUM_MESSAGE_LENGTH/sizeof(ULONG_PTR)];
  82. PAGED_CODE();
  83. if ( SuspendProcess ) {
  84. SuspendProcess = DbgkpSuspendProcess();
  85. }
  86. ApiMsg->ReturnedStatus = STATUS_PENDING;
  87. PS_SET_BITS (&PsGetCurrentProcess()->Flags, PS_PROCESS_FLAGS_CREATE_REPORTED);
  88. st = LpcRequestWaitReplyPortEx (Port,
  89. (PPORT_MESSAGE) ApiMsg,
  90. (PPORT_MESSAGE) &MessageBuffer[0]);
  91. ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
  92. if (NT_SUCCESS (st)) {
  93. RtlCopyMemory(ApiMsg,MessageBuffer,sizeof(*ApiMsg));
  94. }
  95. if (SuspendProcess) {
  96. DbgkpResumeProcess();
  97. }
  98. return st;
  99. }
  100. BOOLEAN
  101. DbgkForwardException(
  102. IN PEXCEPTION_RECORD ExceptionRecord,
  103. IN BOOLEAN DebugException,
  104. IN BOOLEAN SecondChance
  105. )
  106. /*++
  107. Routine Description:
  108. This function is called forward an exception to the calling process's
  109. debug or subsystem exception port.
  110. Arguments:
  111. ExceptionRecord - Supplies a pointer to an exception record.
  112. DebugException - Supplies a boolean variable that specifies whether
  113. this exception is to be forwarded to the process's
  114. DebugPort(TRUE), or to its ExceptionPort(FALSE).
  115. Return Value:
  116. TRUE - The process has a DebugPort or an ExceptionPort, and the reply
  117. received from the port indicated that the exception was handled.
  118. FALSE - The process either does not have a DebugPort or
  119. ExceptionPort, or the process has a port, but the reply received
  120. from the port indicated that the exception was not handled.
  121. --*/
  122. {
  123. PEPROCESS Process;
  124. PVOID Port;
  125. DBGKM_APIMSG m;
  126. PDBGKM_EXCEPTION args;
  127. NTSTATUS st;
  128. BOOLEAN LpcPort;
  129. PAGED_CODE();
  130. args = &m.u.Exception;
  131. //
  132. // Initialize the debug LPC message with default infomaation.
  133. //
  134. DBGKM_FORMAT_API_MSG(m,DbgKmExceptionApi,sizeof(*args));
  135. //
  136. // Get the address of the destination LPC port.
  137. //
  138. Process = PsGetCurrentProcess();
  139. if (DebugException) {
  140. if (PsGetCurrentThread()->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_HIDEFROMDBG) {
  141. Port = NULL;
  142. } else {
  143. Port = Process->DebugPort;
  144. }
  145. LpcPort = FALSE;
  146. } else {
  147. Port = Process->ExceptionPort;
  148. m.h.u2.ZeroInit = LPC_EXCEPTION;
  149. LpcPort = TRUE;
  150. }
  151. //
  152. // If the destination LPC port address is NULL, then return FALSE.
  153. //
  154. if (Port == NULL) {
  155. return FALSE;
  156. }
  157. //
  158. // Fill in the remainder of the debug LPC message.
  159. //
  160. args->ExceptionRecord = *ExceptionRecord;
  161. args->FirstChance = !SecondChance;
  162. //
  163. // Send the debug message to the destination LPC port.
  164. //
  165. if (LpcPort) {
  166. st = DbgkpSendApiMessageLpc(&m,Port,DebugException);
  167. } else {
  168. st = DbgkpSendApiMessage(&m,DebugException);
  169. }
  170. //
  171. // If the send was not successful, then return a FALSE indicating that
  172. // the port did not handle the exception. Otherwise, if the debug port
  173. // is specified, then look at the return status in the message.
  174. //
  175. if (!NT_SUCCESS(st) ||
  176. ((DebugException) &&
  177. (m.ReturnedStatus == DBG_EXCEPTION_NOT_HANDLED || !NT_SUCCESS(m.ReturnedStatus)))) {
  178. return FALSE;
  179. } else {
  180. return TRUE;
  181. }
  182. }